﻿using AutoMapper;
using Coldairarrow.Entity.Base;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.Entity.TD;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_ProductionOrderBusiness : BaseBusiness<PB_ProductionOrder>, IPB_ProductionOrderBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IMapper _mapper;
        readonly IOperatorDept _opdept;
        public PB_ProductionOrderBusiness(IDbAccessor db, IOperator @operator, IMapper mapper, IOperatorDept @opdept)
            : base(db)
        {
            _operator = @operator;
            _mapper = mapper;
            _opdept = @opdept;
        }
        #region 外部接口

        public async Task<PageResult<PB_ProductionOrder>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<PB_ProductionOrder>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_ProductionOrder, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }
            q.Where(x => _operator.Property.DeptIds.Contains(x.DeptId));
            return await q.Where(where).GetPageResultAsync(input);
        }

        /// <summary>
        /// 生产订单返回结果集
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<Entity.PB.PB_ProductionOrderDTO>> GetDataListShowDeptNameAsync(PageInput<PB_ProductionOrderConditionDTO> input)
        {
            Expression<Func<PB_ProductionOrder, PB_DesignList, Base_Department, Base_User, Entity.PB.PB_ProductionOrderDTO>> select = (a, b, c, d) => new Entity.PB.PB_ProductionOrderDTO
            {
                ProjectName = b.ProjectName,
                DLName = b.Name,
                DeptName = c.Name,
                UserName = d.RealName,
                ProjectId = b.ProjectId,
                CompletionStatus = 0,
            };
            var search = input.Search;
            select = select.BuildExtendSelectExpre();
            var q_DesignList = GetIQueryable();
            var q = from a in q_DesignList.AsExpandable()
                        //联合PB_DesignList表
                    join b in Db.GetIQueryable<PB_DesignList>() on a.DesignId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                        //联合Base_Department表
                    join c in Db.GetIQueryable<Base_Department>() on a.DeptId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_User>() on a.CreatorId equals d.Id into ad
                    from d in ad.DefaultIfEmpty()

                    select @select.Invoke(a, b, c, d);



            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var keyword = $"%{search.Keyword}%";
                q = q.Where(x => EF.Functions.Like(search.Condition, keyword));
            }
            if (!search.ProjectName.IsNullOrEmpty())
            {
                q = q.Where(x => x.ProjectName == search.ProjectName);
            }
            if (!search.DLName.IsNullOrEmpty())
            {
                q = q.Where(m => m.POName.Contains(search.DLName));
            }
            if (!search.WorkName.IsNullOrEmpty())
            {
                q = q.Where(m => m.DeptName == search.WorkName);
            }
            if (!search.StartDate.IsNullOrEmpty() && !search.EndDate.IsNullOrEmpty())
            {
                DateTime StartDate = Convert.ToDateTime(Convert.ToDateTime(search.StartDate).Date.ToString());
                DateTime EndDate = Convert.ToDateTime(Convert.ToDateTime(search.EndDate).Date.ToString()).AddDays(1).AddSeconds(-1);
                q = q.Where(x => StartDate <= x.BeginDate && x.EndDate <= EndDate);
            }
            if (!search.ProjectId.IsNullOrEmpty())
            {
                if (search.ProjectId == ("1"))
                {
                    q = q.Where(m => m.State == false);
                }
                else if (search.ProjectId == ("2"))
                {
                    q = q.Where(m => m.State == true);
                }
                else
                {
                    q = q.Where(m => m.ProjectId == search.ProjectId);
                }
            }
            if (!search.IsRefurbishment.IsNullOrEmpty())
            {
                q = q.Where(x => x.IsRefurbishment == search.IsRefurbishment);
            }
            //是否有项目
            if (search.IsProject == 0)
            {
                q = q.Where(m => m.State == false);
            }
            else if (search.IsProject == 1)
            {
                q = q.Where(m => m.State == true);
            }
            List<string> LIS = new List<string>();
            if (search.IsSranslate == 0)
            {
                string sql = "select PB_ProductionOrder.* from PB_ProductionOrder INNER JOIN  PB_DesignList ON  PB_ProductionOrder.DesignId = PB_DesignList.Id WHERE NOT exists(SELECT * FROM PB_DesignDetail WHERE PB_DesignDetail.ParentId = PB_DesignList.Id AND  PB_DesignDetail.State = 2) UNION ALL select* FROM PB_ProductionOrder WHERE State = 0";
                var List = await Db.GetListBySqlAsync<PB_ProductionOrder>(sql);
                foreach (var item in List)
                {
                    LIS.Add(item.Id);
                }
                q = q.Where(m => LIS.Contains(m.Id));
            }
            else if (search.IsSranslate == 1)
            {
                string sql = "select PB_ProductionOrder.* from PB_ProductionOrder LEFT JOIN  PB_DesignList ON  PB_ProductionOrder.DesignId = PB_DesignList.Id LEFT JOIN PB_DesignDetail ON   PB_DesignDetail.ParentId = PB_DesignList.Id WHERE PB_DesignDetail.State = 1 GROUP BY  PB_DesignList.Id,PB_ProductionOrder.Id";
                var List = await Db.GetListBySqlAsync<PB_ProductionOrder>(sql);
                foreach (var item in List)
                {
                    LIS.Add(item.Id);
                }
                q = q.Where(m => LIS.Contains(m.Id));
            }
            if (!search.MaterialKeyword.IsNullOrEmpty())
            {
                string sql = @"select a.ParentId from PB_ProductionOrderDetail as a left join PB_Material as b on a.MaterialId=b.Id where (b.`Name` like '%" + search.MaterialKeyword + "%' or b.`Code` like '%" + search.MaterialKeyword + "%' or b.Spec like '%" + search.MaterialKeyword + "%') group by a.ParentId";
                var List = await Db.GetDataTableWithSqlAsync(sql);
                foreach (DataRow dr in List.Rows)
                {
                    LIS.Add(dr["ParentId"].ToString());
                }
                q = q.Where(m => LIS.Contains(m.Id));
            }

            //生产订单 权限
            q = q.Where(m => _operator.Property.DeptIds.Contains(m.DeptId));

            
            var data= await q.GetPageResultAsync(input);
            data.Data.ForEach(m =>
            {
                string sql = "SELECT IFNULL(SUM(Productionquantity), 0)Productionquantity, IFNULL(SUM(CompleteNums), 0) CompleteNums FROM PB_ProductionOrderDetail WHERE  ParentId = '" + m.Id + "'  GROUP BY ParentId ";
          
                var prodedetail = Db.GetListBySqlAsync<PB_ProductionOrderDetailNums>(sql).Result.FirstOrDefault();
                if (prodedetail.CompleteNums >= prodedetail.Productionquantity)
                {
                    m.CompletionStatus = 1;
                }
                else
                {
                   m.CompletionStatus = 0;
                }
            }
 );
            PageResult<Entity.PB.PB_ProductionOrderDTO> pageResult = new PageResult<Entity.PB.PB_ProductionOrderDTO>();
            pageResult = data;
            List<Entity.PB.PB_ProductionOrderDTO> SS = new List<Entity.PB.PB_ProductionOrderDTO>();
            SS = pageResult.Data;
            if (!input.Search.CompletionStatus.IsNullOrEmpty())
            {
                if (input.Search.CompletionStatus == 0)
                {
                    SS = SS.Where(m => m.CompletionStatus == 0).ToList();
                }
                else
                {
                    SS = SS.Where(m => m.CompletionStatus == 1).ToList();
                }
            }
            pageResult.Data = SS;
            return pageResult;
        }

        /// <summary>
        /// sql获取任务单列表拿出任务单完成状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<Entity.PB.PB_ProductionOrderDTO>> GetDataPercentageList(PageInput<PB_ProductionOrderConditionDTO> input)
        {
            //sql拼接生产任务单
            List<string> ids = new List<string>();
            StringBuilder sql = new StringBuilder();
            sql.AppendLine("SELECT");
            sql.AppendLine("*");
            sql.AppendLine(",((1-bbcount/bcount)*100) as Percentage");
            sql.AppendLine("FROM");
            sql.AppendLine("(");
            sql.AppendLine("SELECT");
            sql.AppendLine("a.*,");
            sql.AppendLine("List.`Name` DLName,");
            sql.AppendLine("project.`Name` ProjectName,");
            sql.AppendLine("IFNULL(SUM(b.Productionquantity), 0) Productionquantity,");
            sql.AppendLine("IFNULL(SUM(b.CompleteNums), 0) CompleteNums,");
            sql.AppendLine("CASE");
            sql.AppendLine("WHEN IFNULL(SUM(b.CompleteNums), 0) >= IFNULL(SUM(b.Productionquantity), 0) THEN");
            sql.AppendLine("1 ELSE 0");
            sql.AppendLine("END CompletionStatus,");
            sql.AppendLine("par.`Name` DeptName,");
            sql.AppendLine("user.RealName UserName,");
            sql.AppendLine("Count(b.Productionquantity) as bcount,");
            sql.AppendLine("Count(case when IFNULL(b.CompleteNums, 0) < IFNULL(b.Productionquantity, 0) then 1 end) as bbcount");
            sql.AppendLine("FROM");
            sql.AppendLine(" PB_ProductionOrder AS a");
            sql.AppendLine("LEFT JOIN PB_DesignList AS List ON a.DesignId = List.Id");
            sql.AppendLine("LEFT JOIN Base_Department AS par on a.DeptId=par.Id");
            sql.AppendLine("LEFT JOIN Base_User AS user on a.CreatorId = user.Id");
            sql.AppendLine("LEFT JOIN PB_Project AS project ON List.ProjectId = project.Id");
            sql.AppendLine("LEFT JOIN PB_ProductionOrderDetail AS b ON b.ParentId = a.Id");
            sql.AppendLine("GROUP BY");
            sql.AppendLine(" a.Id");
            sql.AppendLine(" ) AS T Where 1=1 ");
            if (!input.Search.ProjectName.IsNullOrEmpty()) {
                sql.AppendLine("and T.ProjectName like '%"+input.Search.ProjectName+"%'");
            }
            if (!input.Search.DLName.IsNullOrEmpty()) {
                sql.AppendLine("And T.POName like '%"+input.Search.DLName+"%' ");
            }
            if (!input.Search.IsRefurbishment.IsNullOrEmpty()) {
                sql.AppendLine("And T.IsRefurbishment= '" + input.Search.IsRefurbishment + "' ");
            }
            if (!input.Search.WorkName.IsNullOrEmpty())
            {
                sql.AppendLine("And T.DeptName like '%" + input.Search.WorkName + "%' ");
            }
            if (!input.Search.MaterialKeyword.IsNullOrEmpty())
            {
                string poids = @"select a.ParentId from PB_ProductionOrderDetail as a left join PB_Material as b on a.MaterialId=b.Id where (b.`Name` like '%" + input.Search.MaterialKeyword + "%' or b.`Code` like '%" + input.Search.MaterialKeyword + "%' or b.Spec like '%" + input.Search.MaterialKeyword + "%') group by a.ParentId";
                var List = await Db.GetDataTableWithSqlAsync(poids);
                foreach (DataRow dr in List.Rows)
                {
                    ids.Add(dr["ParentId"].ToString());
                }
                string str = string.Join("\',\'", ids);
                string str2 = "(\'" + str + "\')";
                sql.AppendLine("And T.Id in "+str2+"");
            }
            if (!input.Search.StartDate.IsNullOrEmpty() && !input.Search.EndDate.IsNullOrEmpty())
            {

                sql.AppendLine("AND  T.BeginDate >= '"+input.Search.StartDate+" 00:00:00'    AND T.EndDate<='"+input.Search.EndDate+" 23:59:59'");
            }
            if (input.Search.IsProject == 0)
            {
                sql.AppendLine("And T.State=0");
            }
            else if (input.Search.IsProject == 1)
            {
                sql.AppendLine("And T.State=1");
            }
            if (input.Search.State==true) {
                sql.AppendLine("And T.Status=1");
            }
            List<string> Addornot = new List<string>();
            if (input.Search.IsSranslate == 0)
            {
                string Addornotsql = "select PB_ProductionOrder.* from PB_ProductionOrder INNER JOIN  PB_DesignList ON  PB_ProductionOrder.DesignId = PB_DesignList.Id WHERE NOT exists(SELECT * FROM PB_DesignDetail WHERE PB_DesignDetail.ParentId = PB_DesignList.Id AND  PB_DesignDetail.State = 2) UNION ALL select* FROM PB_ProductionOrder WHERE State = 0";
                var List = await Db.GetListBySqlAsync<PB_ProductionOrder>(Addornotsql);
                foreach (var item in List)
                {
                    Addornot.Add(item.Id);
                }
                string str = string.Join("\',\'", Addornot);
                string str2 = "(\'" + str + "\')";
                sql.AppendLine("And T.Id in " + str2 + "");

            }
            else if (input.Search.IsSranslate == 1)
            {
                string Addornot3 = "select PB_ProductionOrder.* from PB_ProductionOrder LEFT JOIN  PB_DesignList ON  PB_ProductionOrder.DesignId = PB_DesignList.Id LEFT JOIN PB_DesignDetail ON   PB_DesignDetail.ParentId = PB_DesignList.Id WHERE PB_DesignDetail.State = 1 GROUP BY  PB_DesignList.Id,PB_ProductionOrder.Id";
                var List = await Db.GetListBySqlAsync<PB_ProductionOrder>(Addornot3);
                foreach (var item in List)
                {
                    Addornot.Add(item.Id);
                }
                string str = string.Join("\',\'", Addornot);
                string str2 = "(\'" + str + "\')";
                sql.AppendLine("And T.Id in " + str2 + "");
            }
            if (input.Search.CompletionStatus == 0) {
                sql.AppendLine("And T.CompletionStatus=0");
            } else if (input.Search.CompletionStatus==1) {
                sql.AppendLine("And T.CompletionStatus=1");
            }
            sql.AppendLine("ORDER By  T.CreateTime "+input.SortType+" ");
            var res = await Db.GetListBySqlAsync<Entity.PB.PB_ProductionOrderDTO>(sql.ToString());
            int pagecount;//总页数
            List<Entity.PB.PB_ProductionOrderDTO> listpro_down = res.ToList();//一个要分页的，类型数据集合，存储的是所有的数据
            List<Entity.PB.PB_ProductionOrderDTO> productes = new List<Entity.PB.PB_ProductionOrderDTO>();//用来存储要展示的数据
            int pagees = listpro_down.Count;//所有数据的总条数
                                            //计算总页数
            if (pagees % input.PageRows == 0)
            {
                pagecount = pagees / input.PageRows;
            }
            else
            {
                pagecount = (pagees / input.PageRows) + 1;
            }
            productes = listpro_down.Skip((input.PageIndex - 1) * input.PageRows).Take(input.PageRows).ToList();//分页的重点
            return new PageResult<Entity.PB.PB_ProductionOrderDTO> { Data = productes, Total = pagees };
        }

        public async Task<PB_ProductionOrder> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        /// <summary>
        /// 大屏显示当月生产计划数量(不含当月之前已完成量)和生产进度
        /// </summary>
        /// <param name="Month">前第几月</param>
        /// <returns>当月生产计划数量和生产进度</returns>
        public Coldairarrow.Entity.DTO.ScreenDisplayProgressDTO GetMonthPlanNums(int Month)
        {
            string strSQL = @"SELECT '本月计划产量(件)' AS label,IFNULL(SUM(a.value),0) AS value,
IF(SUM(a.value) IS NULL OR SUM(a.value)=0,0,IF(IFNULL(SUM(b.data),0)>SUM(a.value),100,(IFNULL(SUM(b.data),0)/SUM(a.value)*100))) AS data 
FROM
(SELECT Id,SUM(b.value) AS value
FROM
(SELECT po.Id,IFNULL(SUM(pd.Productionquantity),0)  AS value
FROM PB_ProductionOrderDetail pd
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1  AND po.IsRefurbishment=1 AND date_format(po.EndDate, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
GROUP BY po.Id
UNION
SELECT poId AS Id,-IFNULL(SUM(a.data),0) AS value
FROM
(SELECT jb.Id AS jbId,po.Id AS poId,IFNULL(jb.StatisticsNums,0) AS data
FROM PB_JobBooking jb
JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND date_format(jb.ReportTime, '%Y %m')<date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1 AND po.IsRefurbishment=1 AND date_format(po.EndDate, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
) a GROUP BY poId) b GROUP BY b.Id) a
LEFT JOIN
(SELECT poId AS Id,IFNULL(SUM(a.data),0) AS data 
FROM
(SELECT jb.Id AS jbId,po.Id AS poId,IFNULL(jb.StatisticsNums,0) AS data
FROM PB_JobBooking jb
JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND date_format(jb.ReportTime, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1 AND po.IsRefurbishment=1 AND date_format(po.EndDate, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
)a GROUP BY a.poId) b ON a.Id=b.Id";
            var res = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayProgressDTO>(strSQL).Result.FirstOrDefault();
            if (res != null)
            {
                //四舍五入保留两位小数
                res.value = Convert.ToDecimal(res.value.ToString("#0.##"));
                res.data = Convert.ToDecimal(res.data.ToString("#0.##"));
                return res;
            }
            else
            {
                throw new BusException("暂无数据");
            }
        }
        /// <summary>
        /// 大屏显示当月生产计划重量(吨)和生产进度
        /// </summary>
        /// <param name="Month">前第几月</param>
        /// <returns></returns>
        public Coldairarrow.Entity.DTO.ScreenDisplayProgressDTO GetMonthPlanWeights(int Month)
        {
            string strSQL = @"SELECT '本月计划产量(吨)' AS label,IFNULL(SUM(a.value),0)/1000 AS value,
IF(SUM(a.value) IS NULL OR SUM(a.value)=0,0,IF(IFNULL(SUM(b.data),0)>SUM(a.value),100,(IFNULL(SUM(b.data),0)/SUM(a.value)*100))) AS data 
FROM
(SELECT Id,SUM(b.value) AS value
FROM
(SELECT po.Id,IFNULL(SUM(pd.Productionquantity*m.Weight),0) AS value
FROM PB_ProductionOrderDetail pd
JOIN PB_Material m ON pd.MaterialId=m.Id
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1  AND po.IsRefurbishment=1 AND date_format(po.EndDate, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
GROUP BY po.Id
UNION
SELECT poId AS Id,-IFNULL(SUM(a.data),0) AS value
FROM
(SELECT jb.Id AS jbId,po.Id AS poId,IFNULL(IFNULL(jb.StatisticsNums,0)*m.Weight,0) AS data
FROM PB_JobBooking jb
JOIN PB_Material m ON jb.MaterialId=m.Id
JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND date_format(jb.ReportTime, '%Y %m')<date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1 AND po.IsRefurbishment=1 AND date_format(po.EndDate, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
) a GROUP BY poId) b GROUP BY b.Id) a
LEFT JOIN
(SELECT poId AS Id,IFNULL(SUM(a.data),0) AS data 
FROM
(SELECT jb.Id AS jbId,po.Id AS poId,IFNULL(IFNULL(jb.StatisticsNums,0)*m.Weight,0) AS data
FROM PB_JobBooking jb
JOIN PB_Material m ON jb.MaterialId=m.Id
JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND date_format(jb.ReportTime, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1 AND po.IsRefurbishment=1 AND date_format(po.EndDate, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
)a GROUP BY a.poId) b ON a.Id=b.Id";


            var res = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayProgressDTO>(strSQL).Result.FirstOrDefault();
            if (res != null)
            {
                //四舍五入保留两位小数
                res.value = Convert.ToDecimal(res.value.ToString("#0.##"));
                res.data = Convert.ToDecimal(res.data.ToString("#0.##"));
            }
            return res;
        }
        /// <summary>
        /// 大屏显示当日总计划重量(吨)，不含当日以前已完成量
        /// </summary>
        /// <param name="Day"></param>
        /// <returns></returns>
        public Coldairarrow.Entity.DTO.ScreenDisplayValueDTO GetTodayPlanWeight(int Day)
        {
            //因为数据经常为0，去掉当日在任务中的时间要求DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY) BETWEEN DATE(po.BeginDate) AND DATE(po.EndDate)
            //            string strSQL = @"SELECT IFNULL(SUM(t.value),0) AS value
            //FROM
            //(
            //SELECT IFNULL(SUM(IFNULL(pd.Productionquantity,0))-IFNULL(SUM(finish.value),0),0)/1000 AS value
            //FROM PB_ProductionOrderDetail pd
            //JOIN 
            //(SELECT DISTINCT pd.Id
            //FROM PB_JobBooking jb
            //JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)=DATE(jb.ReportTime)
            //) plan ON pd.Id=plan.Id
            //LEFT JOIN
            //(SELECT pd.Id,SUM(IF(jb.StatisticsNums IS NULL OR jb.StatisticsNums=0,jb.Nums,jb.StatisticsNums)*m.Weight) AS value
            //FROM PB_JobBooking jb
            //JOIN PB_Material m ON jb.MaterialId=m.Id
            //JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)>DATE(jb.ReportTime)
            //GROUP BY pd.Id) finish ON plan.Id=finish.Id) t";
            string strSQL = @"SELECT IFNULL(SUM(t.`value`)/1000,0) AS value
FROM
(SELECT IFNULL(plan.`value`,0)-IFNULL(finished.`value`,0) AS value
FROM
(SELECT pd.Id,m.Id AS mId,m.Weight,m.IsProduct,pd.Productionquantity*m.Weight AS value
FROM PB_ProductionOrderDetail pd
JOIN PB_Material m ON pd.MaterialId=m.Id
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.`Status`=1 AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY) BETWEEN DATE(po.BeginDate) AND DATE(po.EndDate)
UNION
SELECT DISTINCT pd.Id,m.Id AS mId,m.Weight,m.IsProduct,pd.Productionquantity*m.Weight AS value
FROM PB_JobBooking jb
JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)=DATE(ReportTime)
JOIN PB_Material m ON pd.MaterialId=m.Id) plan
LEFT JOIN
(SELECT jb.ParentId AS Id,SUM(IFNULL(jb.StatisticsNums,0)*m.Weight) AS value
FROM PB_JobBooking jb
JOIN PB_Material m ON jb.MaterialId=m.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)>DATE(jb.ReportTime)
GROUP BY jb.ParentId
) finished ON plan.Id=finished.Id) t";
            var res = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayValueDTO>(strSQL).Result.FirstOrDefault();
            if (res != null)
            {
                //四舍五入保留两位小数
                res.value = Convert.ToDouble(res.value.ToString("#0.##"));
            }
            return res;
        }
        /// <summary>
        /// 大屏显示当日总完成重量(吨)
        /// </summary>
        /// <param name="Day"></param>
        /// <returns></returns>
        public Coldairarrow.Entity.DTO.ScreenDisplayValueDTO GetTodayFinishWeight(int Day)
        {
            //因为数据经常为0，去掉当日在任务中的时间要求DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY) BETWEEN DATE(po.BeginDate) AND DATE(po.EndDate)
            string strSQL = @"SELECT IFNULL(SUM(IFNULL(jb.StatisticsNums,0)*m.Weight)/1000,0) AS value
FROM PB_JobBooking jb
JOIN PB_Material m ON jb.MaterialId=m.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)=DATE(jb.ReportTime)
-- JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id 
-- JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1 AND po.IsRefurbishment=1";
            var res = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayValueDTO>(strSQL).Result.FirstOrDefault();
            if (res != null)
            {
                //四舍五入保留两位小数
                res.value = Convert.ToDouble(res.value.ToString("#0.##"));
            }
            return res;
        }
        /// <summary>
        /// 大屏显示当日总计划完成率
        /// </summary>
        /// <param name="Day"></param>
        /// <returns></returns>
        public Coldairarrow.Entity.DTO.ScreenDisplayValue3DTO GetTodayFinishRate(int Day)
        {
            //            string strSQL = @"SELECT IFNULL(IF(SUM(plan.Productionquantity)<SUM(finished.data2) OR SUM(finish.data1)>(SUM(plan.Productionquantity)-SUM(finished.data2))
            //,100,IFNULL(SUM(finish.data1),0)/(IFNULL(SUM(plan.Productionquantity),0)-IFNULL(SUM(finished.data2),0))*100),0) AS value
            //FROM
            //(SELECT jb.ParentId AS Id,IFNULL(SUM(IF(jb.StatisticsNums IS NULL OR jb.StatisticsNums=0,jb.Nums,jb.StatisticsNums)*m.Weight)/1000,0) AS data1
            //FROM PB_JobBooking jb
            //JOIN PB_Material m ON jb.MaterialId=m.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)=DATE(jb.ReportTime)
            //GROUP BY jb.ParentId) finish
            //JOIN
            //PB_ProductionOrderDetail plan ON finish.Id=plan.Id
            //LEFT JOIN
            //(SELECT jb.ParentId AS Id,IFNULL(SUM(IF(jb.StatisticsNums IS NULL OR jb.StatisticsNums=0,jb.Nums,jb.StatisticsNums)*m.Weight),0) AS data2
            //FROM PB_JobBooking jb
            //JOIN PB_Material m ON jb.MaterialId=m.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)>DATE(jb.ReportTime)
            //GROUP BY jb.ParentId) finished ON finish.Id=finished.Id";
            string strSQL = @"SELECT IFNULL(SUM(t.`value`)/1000,0) AS value
FROM
(SELECT IFNULL(plan.`value`,0)-IFNULL(finished.`value`,0) AS value
FROM
(SELECT pd.Id,m.Id AS mId,m.Weight,m.IsProduct,pd.Productionquantity*m.Weight AS value
FROM PB_ProductionOrderDetail pd
JOIN PB_Material m ON pd.MaterialId=m.Id
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.`Status`=1 AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY) BETWEEN DATE(po.BeginDate) AND DATE(po.EndDate)
UNION
SELECT DISTINCT pd.Id,m.Id AS mId,m.Weight,m.IsProduct,pd.Productionquantity*m.Weight AS value
FROM PB_JobBooking jb
JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)=DATE(ReportTime)
JOIN PB_Material m ON pd.MaterialId=m.Id) plan
LEFT JOIN
(SELECT jb.ParentId AS Id,SUM(IFNULL(jb.StatisticsNums,0)*m.Weight) AS value
FROM PB_JobBooking jb
JOIN PB_Material m ON jb.MaterialId=m.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)>DATE(jb.ReportTime)
GROUP BY jb.ParentId
) finished ON plan.Id=finished.Id) t";

            double plan = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayValueDTO>(strSQL).Result.FirstOrDefault().value;

            strSQL = @"SELECT IFNULL(SUM(IFNULL(jb.StatisticsNums,0)*m.Weight)/1000,0) AS value
FROM PB_JobBooking jb
JOIN PB_Material m ON jb.MaterialId=m.Id AND DATE_SUB(CURDATE(),INTERVAL " + Day.ToString() + @" DAY)=DATE(jb.ReportTime)
-- JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id 
-- JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1 AND po.IsRefurbishment=1";
            double finish = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayValueDTO>(strSQL).Result.FirstOrDefault().value;
            double resValue = finish > plan ? 100 : (double)(finish / plan) * 100;
            //var res = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayValueDTO>(strSQL).Result.FirstOrDefault();
            //if (res != null)
            //{
            //    //四舍五入保留两位小数
            //    return new Entity.DTO.ScreenDisplayValue3DTO { value = res.value.ToString("#0.##") + "%" };
            //}
            //else
            //{
            //    return null;
            //}
            return new ScreenDisplayValue3DTO { value = resValue.ToString("#0.##") + "%" };
        }
        /// <summary>
        /// 大屏显示当月指定车间总完成重量(吨)
        /// </summary>
        /// <param name="Month">前第几月</param>
        /// <param name="WorkShop">车间名称</param>
        /// <returns></returns>
        public Coldairarrow.Entity.DTO.ScreenDisplayValueDTO GetMonthFinishWeightByWorkShop(int Month, string WorkShop)
        {
            string strSQL = @"SELECT IFNULL(SUM(a.data)/1000,0) AS value
FROM
(SELECT jb.Id,IFNULL(IFNULL(jb.StatisticsNums,0)*m.Weight,0) AS data
FROM PB_JobBooking jb
JOIN PB_Material m ON jb.MaterialId=m.Id
JOIN Base_Department d ON jb.WorkshopId=d.Id AND d.FullName LIKE '%" + WorkShop + @"%'
JOIN PB_ProductionOrderDetail pd ON jb.ParentId=pd.Id AND date_format(jb.ReportTime, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
JOIN PB_ProductionOrder po ON pd.ParentId=po.Id AND po.Status=1 AND po.IsRefurbishment=1 AND date_format(po.EndDate, '%Y %m')=date_format(DATE_SUB(curdate(), INTERVAL " + Month.ToString() + @" MONTH),'%Y %m')
) a";
            var res = Db.GetListBySqlAsync<Coldairarrow.Entity.DTO.ScreenDisplayValueDTO>(strSQL).Result.FirstOrDefault();
            if (res != null)
            {
                //四舍五入保留两位小数
                res.value = Convert.ToDouble(res.value.ToString("#0.##"));
            }
            return res;
        }

        public async Task AddDataAsync(PB_ProductionOrder data)
        {
            string QCstr = "02," + data.Id;
            data.QrCode = QCstr;
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(PB_ProductionOrder data)
        {
            string QCstr = "02," + data.Id;
            data.QrCode = QCstr;
            await UpdateAsync(data);
        }

        [DataDeleteLog(UserLogType.生产任务单, "Id", "生产任务单Id")]
        public async Task DeleteDataAsync(List<string> ids)
        {

            if (await Db.GetIQueryable<PB_OutsourcingBill>().AnyAsync(x => ids.Contains(x.RefCode)))
            {
                throw new BusException("删除失败！该生产任务单已有外协加工");
            }
            List<PB_DispatchDetail> DispatchDetail = await Db.GetIQueryable<PB_DispatchDetail>().Where(x => ids.Contains(x.OrderId)).ToListAsync();
            if (DispatchDetail.Count > 0)
            {
                throw new BusException("任务单有派工不能删除");
            }
            string strid = "";
            foreach (var item in ids)
            {
                strid += "'" + item + "',";
            }
            strid = strid.Substring(0, strid.Length - 1);
            await ExecuteSqlAsync("delete from PB_ProductionOrderDetail where ParentId in (" + strid + ")");
            await DeleteAsync(ids);
        }

        public async Task<List<PB_ProductionOrder>> GetPDADataListAsync(PageInput<ConditionDTO> input)
        {
            var UserId = _operator.UserId;
            var q = GetIQueryable().Where(s => s.CreatorId == UserId).Select(s => new PB_ProductionOrder { Id = s.Id, Code = s.Code, CreateTime = s.CreateTime }).OrderByDescending(s => s.CreateTime);
            var where = LinqHelper.True<PB_ProductionOrder>();
            var search = input.Search;
            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_ProductionOrder, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            var res = await q.ToListAsync();
            where = where.And(x => _operator.Property.DeptIds.Contains(x.DeptId));
            return res;
        }
        public IQueryable<T> GetQueryable<T>() where T : class, new()
        {
            return Db.GetIQueryable<T>();
        }

        public async Task<string> GetDataLisJson(string id)
        {
            var q = GetQueryable<PB_ProductionOrder>().Where(s => s.Id == id);
            //List<PB_ProductionOrderDetailDTO> list = await _pbddb.GetDataListAsyncs(id);
            //List<DataTypeinfos> list2 = await _pbddb.GetDataListAsyncs(id);
            //var arr = list.ToList();
            //var Data = new
            //{
            //    Id = q,
            //    Sub = list2.ToArray(),
            //};
            //string Json = Data.ToJson();
            string Json = "";
            return Json;
        }

        public async Task<PB_ProductionOrderList> GetDataListInfo(string ParentId)
        {
            PB_ProductionOrderList pblist = new PB_ProductionOrderList();
            Expression<Func<PB_ProductionOrder, PB_DesignList, Base_Department, Entity.PB.PB_ProductionOrderDTO>> selects = (a, b, c) => new Entity.PB.PB_ProductionOrderDTO
            {
                DLName = b.Name,
                ProjectName = b.ProjectName,
                DeptName = c.Name
            };
            selects = selects.BuildExtendSelectExpre();
            var qdata = from a in Db.GetIQueryable<PB_ProductionOrder>().AsExpandable()
                        join b in Db.GetIQueryable<PB_DesignList>() on a.DesignId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<Base_Department>() on a.DeptId equals c.Id into ac
                        from c in ac.DefaultIfEmpty()
                        select @selects.Invoke(a, b, c);
            pblist.mainData = await qdata.Where(x => x.Id == ParentId).FirstOrDefaultAsync();
            //Expression<Func<PB_ProductionOrderDetail, PB_Material, PB_MaterialType, Base_UnitItems, Entity.PB.PB_ProductionOrderDetailDTO>> select = (a, b, c, d) => new Entity.PB.PB_ProductionOrderDetailDTO
            //{

            //    MaterialID = b.Id,//物料编号
            //    MaterialName = b.Name,//物料名称
            //    MaterialTypeId = c.Name,//类型名称
            //    MaterialCode = b.Code,//物料编号
            //    PackingSpec = b.Spec, //物料规格
            //    Weight = b.Weight,//理论重量
            //    UnitGroupName = d.Name,
            //};
            //select = select.BuildExtendSelectExpre();
            //var q = from a in Db.GetIQueryable<PB_ProductionOrderDetail>().AsExpandable()
            //        join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
            //        from b in ab.DefaultIfEmpty()
            //        join c in Db.GetIQueryable<PB_MaterialType>() on b.MaterialTypeId equals c.Id into ac
            //        from c in ac.DefaultIfEmpty()
            //        join d in Db.GetIQueryable<Base_UnitItems>() on b.storageId equals d.Id into ad
            //        from d in ad.DefaultIfEmpty()
            //        select @select.Invoke(a, b, c, d);
            //q = q.Where(x => x.ParentId == ParentId);
            //q = q.OrderBy(m=>m.Id);
            //var aa = await q.ToListAsync();

            //foreach (var item in aa)
            //{
            //    string sql = "SELECT Count(a.Id) DispatchNums FROM  PB_DispatchDetail AS a  	LEFT JOIN PB_Dispatch AS b ON a.ParentId = b.Id  WHERE   OrderId = '" + ParentId + "' AND OrderDetailId = '" + item.Id + "' AND b.State = 0   GROUP BY OrderId,OrderDetailId";
            //    var DispatchStatusCount = await Db.GetListBySqlAsync<DispatchStatusCount>(sql);
            //    if (DispatchStatusCount.Count > 0)
            //    {
            //        item.DispatchStatus = 1;
            //    }
            //    else
            //    {
            //        item.DispatchStatus = 0;
            //    }
            //}
            //pblist.subData = aa;


            #region 改为直接操作sql
            StringBuilder sql=new StringBuilder();
            sql.Append("SELECT ");
            sql.Append("`p`.`WarehousingTime`, ");
            sql.Append("`p`.`Id`, ");
            sql.Append("`p`.`ParentId`, ");
            sql.Append("`p`.`MaterialId`, ");
            sql.Append("`p`.`ProcecureId`, ");
            sql.Append("`p`.`WorkshopId`, ");
            sql.Append("`p`.`StationId`, ");
            sql.Append("`p`.`Nums`, ");
            sql.Append("`p`.`StartDate`, ");
            sql.Append("`p`.`EndDate`, ");
            sql.Append("`p`.`Remarks`, ");
            sql.Append("`p`.`CreateTime`, ");
            sql.Append("`p`.`CreatorId`, ");
            sql.Append("`p`.`Deleted`, ");
            sql.Append("`p`.`HasCheck`, ");
            sql.Append("`p`.`QrCode`, ");
            sql.Append("`p`.`Finishedproduct`, ");
            sql.Append("`p`.`Ofmaterial`, ");
            sql.Append("`p`.`Holespacing`, ");
            sql.Append("`p`.`Productionquantity`, ");
            sql.Append("`p`.`CompleteNums`, ");
            sql.Append("`p`.`State`, ");
            sql.Append("`p0`.`Id` AS `MaterialID`, ");
            sql.Append("`p0`.`Name` AS `MaterialName`, ");
            sql.Append("`p1`.`Name` AS `MaterialTypeId`, ");
            sql.Append("`p0`.`Code` AS `MaterialCode`, ");
            sql.Append("`p0`.`Spec` AS `PackingSpec`, ");
            sql.Append("`p0`.`Weight`, ");
            sql.Append("`b`.`Name` AS `UnitGroupName`  ");
            sql.Append("FROM ");
            sql.Append("`PB_ProductionOrderDetail` AS `p` ");
            sql.Append("LEFT JOIN `PB_Material` AS `p0` ON `p`.`MaterialId` = `p0`.`Id` ");
            sql.Append("LEFT JOIN `PB_MaterialType` AS `p1` ON `p0`.`MaterialTypeId` = `p1`.`Id` ");
            sql.Append("LEFT JOIN `Base_UnitItems` AS `b` ON `p0`.`storageId` = `b`.`Id`  ");
            sql.Append("WHERE ");
            sql.Append("`p`.`ParentId` = '"+ ParentId + "'  ");
            sql.Append("ORDER BY ");
            sql.Append("`p`.`Id` ");
            var detailDTO = await Db.GetListBySqlAsync<Entity.PB.PB_ProductionOrderDetailDTO>(sql.ToString());
            #endregion

            foreach (var item in detailDTO)
            {
                string tmpSql = "SELECT Count(a.Id) DispatchNums FROM  PB_DispatchDetail AS a LEFT JOIN PB_Dispatch AS b ON a.ParentId = b.Id WHERE OrderId = '" + ParentId + "' AND OrderDetailId = '" + item.Id + "' AND b.State  <> 1 GROUP BY OrderId,OrderDetailId";
                var DispatchStatusCount = await Db.GetListBySqlAsync<DispatchStatusCount>(tmpSql);
                if (DispatchStatusCount.Count > 0)
                {
                    item.DispatchStatus = 1;
                }
                else
                {
                    item.DispatchStatus = 0;
                }
            }
            pblist.subData = detailDTO;
            return pblist;
        }

        public async Task<PB_ProductionOrderList> GetDataListDetailed(string ParentId)
        {
            PB_ProductionOrderList pblist = new PB_ProductionOrderList();
            //pblist.mainData = GetQueryable<PB_ProductionOrderDTO>().Where(x => x.Id == ParentId).FirstOrDefault();
            Expression<Func<PB_ProductionOrder, PB_DesignList, Entity.PB.PB_ProductionOrderDTO>> selects = (a, b) => new Entity.PB.PB_ProductionOrderDTO
            {
                DLName = b.Name
            };
            selects = selects.BuildExtendSelectExpre();
            var qdata = from a in Db.GetIQueryable<PB_ProductionOrder>().AsExpandable()
                        join b in Db.GetIQueryable<PB_DesignList>() on a.DesignId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        select @selects.Invoke(a, b);
            pblist.mainData = await qdata.Where(x => x.Id == ParentId).FirstOrDefaultAsync();
            string sqlMain = @"select SUM(a.Nums) as Nums,SUM(a.Productionquantity) as Productionquantity,a.Finishedproduct,d.`Name` as UnitGroupName,a.MaterialId,b.`Code` as MaterialCode,a.Ofmaterial,b.Spec as PackingSpec,b.`Name` as MaterialName,a.Remarks,max(a.QrCode) QrCode from PB_ProductionOrderDetail as a LEFT JOIN PB_Material as b on a.MaterialId=b.Id LEFT JOIN PB_MaterialType as c on b.MaterialTypeId=c.Id LEFT JOIN Base_UnitGroup as d on b.UnitGroupId=d.Id where a.ParentId='" + ParentId + "' group by a.Finishedproduct,d.`Name`,a.MaterialId,b.`Code`,a.Ofmaterial,b.Spec,b.`Name`,a.Remarks";
            DataTable dt = await GetDataTableWithSqlAsync(sqlMain);
            List<Entity.PB.PB_ProductionOrderDetailDTO> list = new List<Entity.PB.PB_ProductionOrderDetailDTO>();
            foreach (DataRow dr in dt.Rows)
            {
                Entity.PB.PB_ProductionOrderDetailDTO pbdto = new Entity.PB.PB_ProductionOrderDetailDTO();
                pbdto.Nums = Convert.ToInt32(dr["Nums"]);
                pbdto.Productionquantity = Convert.ToInt32(dr["Productionquantity"]);
                pbdto.Finishedproduct = dr["Finishedproduct"].ToString();
                pbdto.UnitGroupName = dr["UnitGroupName"].ToString();
                pbdto.MaterialId = dr["MaterialId"].ToString();
                pbdto.MaterialCode = dr["MaterialCode"].ToString();
                pbdto.Ofmaterial = dr["Ofmaterial"].ToString();
                pbdto.PackingSpec = dr["PackingSpec"].ToString();
                pbdto.MaterialName = dr["MaterialName"].ToString();
                pbdto.Remarks = dr["Remarks"].ToString();
                pbdto.QrCode = dr["QrCode"].ToString();
                list.Add(pbdto);
            }
            pblist.subData = list;
            return pblist;
        }

        [DataAddLog(UserLogType.生产任务单, "POName", "生产任务单")]
        [DataRepeatValidate(new string[] { "Code", "POName" }, new string[] { "任务单编号", "任务单名称" }, allData: false, matchOr: false)]
        [Transactional]
        public async Task AddData(Entity.DTO.PB_ProductionOrderListDTO data)
        {
            Base_User bdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            PB_ProductionOrder b_ProductionOrder = new PB_ProductionOrder
            {
                Id = data.Id,//编号
                Code = data.Code,//生产订单编号
                DesignId = data.DesignId,//生产订单编号
                POName = data.POName,//生产订单名称
                Type = data.Type,//生产订单类别
                BeginDate = data.BeginDate,//开始日期
                EndDate = data.EndDate,//结束日期
                Remarks = data.Remarks,//备注
                DeptId = data.DeptId,//组织id
                CreateTime = data.CreateTime,//创建时间
                CreatorId = data.CreatorId,//创建人id
                Deleted = data.Deleted,//是否删除
                Status = 0,//默认生产中 0 生产中  1已完成  2 作废
                Taskstatus = 0,//任务单状态 0 正常  1异常  
                BatchNumber = data.BatchNumber,
                State = data.State,
                IsNew = true,//是否为新生产 0否 1是
                IsRefurbishment = data.IsRefurbishment,  //是否翻新
                QrCode = h_ProductionOrder + "," + data.Id,//二维码
            };
            await InsertAsync(b_ProductionOrder);
            var addDetail = data.subData.Select(x => new PB_ProductionOrderDetail
            {
                Id = IdHelper.GetId(),//id
                ParentId = data.Id,//主表信息
                MaterialId = x.MaterialId,//物料编号
                ProcecureId = x.ProcecureId,//工序编号
                Nums = x.Nums,//计划数量
                Remarks = x.Remarks,//备注
                StartDate = x.StartDate,//开工日期
                EndDate = x.EndDate,//完工日期
                CreateTime = data.CreateTime,
                CreatorId = data.CreatorId,//创建人
                Deleted = false,//为删除
                HasCheck = true,//是否质检
                QrCode = "",//条形码
                WorkshopId = x.WorkshopId,//车间
                StationId = x.StationId,//公位
                Finishedproduct = x.Finishedproduct,//成品
                Ofmaterial = x.Ofmaterial,//材质
                Holespacing = x.Holespacing,//孔距
                Productionquantity = x.Productionquantity,//生产数量
                CompleteNums = 0,     //已完成数量
                State = 0
            }).ToList();
            foreach (var item in addDetail)
            {
                item.QrCode = h_ProductionOrderDetail + "," + item.ParentId + "," + item.Id;
            }
            await Db.InsertAsync<PB_ProductionOrderDetail>(addDetail);
        }

        [DataEditLog(UserLogType.生产任务单, "POName", "生产任务单")]
        [DataRepeatValidate(new string[] { "Code", "POName" }, new string[] { "任务单编号", "任务单名称" }, allData: false, matchOr: false)]
        [Transactional]
        public async Task UpdateData(Entity.DTO.PB_ProductionOrderListDTO data)
        {
            //生产任务单可编辑主表
            PB_ProductionOrder pB_ProductionOrder = new PB_ProductionOrder();
            pB_ProductionOrder.Id = data.Id;
            pB_ProductionOrder.Code = data.Code;
            pB_ProductionOrder.DesignId = data.DesignId;
            pB_ProductionOrder.POName = data.POName;
            pB_ProductionOrder.Type = data.Type;
            pB_ProductionOrder.BeginDate = data.BeginDate;
            pB_ProductionOrder.EndDate = data.EndDate;
            pB_ProductionOrder.Remarks = data.Remarks;
            pB_ProductionOrder.DeptId = data.DeptId;
            pB_ProductionOrder.Taskstatus = data.Taskstatus;
            pB_ProductionOrder.BatchNumber = data.BatchNumber;

            pB_ProductionOrder.State = data.State;
            pB_ProductionOrder.CreateTime = data.CreateTime;
            pB_ProductionOrder.CreatorId = data.CreatorId;
            pB_ProductionOrder.Deleted = data.Deleted;
            pB_ProductionOrder.Status = data.Status;
            pB_ProductionOrder.IsNew = data.IsNew;
            pB_ProductionOrder.QrCode = data.QrCode;
            pB_ProductionOrder.IsRefurbishment = data.IsRefurbishment;
            await Db.UpdateAsync(pB_ProductionOrder);

            //进来之前先删除明细信息
            await ExecuteSqlAsync(" delete from PB_ProductionOrderDetail where ParentId='" + data.Id + "'");
            var addDetail = data.subData.Select(x => new PB_ProductionOrderDetail
            {
                Id = IdHelper.GetId(),//id
                ParentId = data.Id,//主表信息
                MaterialId = x.MaterialId,//物料编号
                ProcecureId = x.ProcecureId,//工序编号
                Nums = x.Nums,//计划数量
                Remarks = x.Remarks,//备注
                StartDate = x.StartDate,//开工日期
                EndDate = x.EndDate,//完工日期
                CreateTime = data.CreateTime,
                CreatorId = data.CreatorId,//创建人
                Deleted = false,//为删除
                HasCheck = true,//是否质检
                QrCode = "",//条形码
                WorkshopId = x.WorkshopId,//车间
                StationId = x.StationId,//公位
                Finishedproduct = x.Finishedproduct,//成品
                Ofmaterial = x.Ofmaterial,//材质
                Holespacing = x.Holespacing,//孔距
                Productionquantity = x.Productionquantity,//生产数量
                CompleteNums = 0,     //已完成数量
                State = 0
            }).ToList();
            foreach (var item in addDetail)
            {
                item.QrCode = h_ProductionOrderDetail + "," + item.ParentId + "," + item.Id;
            }
            await Db.InsertAsync<PB_ProductionOrderDetail>(addDetail);
        }

        //查找生产订单
        public async Task<PageResult<PB_ProductionOrder>> GetDataSelectAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<PB_ProductionOrder>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<PB_ProductionOrder, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }
            where = where.And(x => _operator.Property.DeptIds.Contains(x.DeptId));
            return await q.Where(where).GetPageResultAsync(input);
        }

        /// <summary>
        /// 审核生产任务单 true 审核成功 false 报废
        /// </summary>
        /// <param name="idIn"></param>
        /// <param name="judge"></param>
        /// <returns></returns>
        public async Task<AjaxResult> SaveEditTOexamineOrder(string idIn, Int32 judge)
        {
            int Return = 0;
            if (judge == 1)
            {
                Return = await ExecuteSqlAsync("UPDATE  PB_ProductionOrder set Status=1    where Id='" + idIn + "';");   //审核
            }
            else if (judge == 3)
            {
                string sql = "select detail.* from PB_DispatchDetail  as detail LEFT JOIN PB_Dispatch as dispatch on detail.ParentId = dispatch.Id where detail.OrderId = '"+idIn+"'  and dispatch.State = 0";
                List<PB_DispatchDetail> DispatchDetail = await Db.GetListBySqlAsync<PB_DispatchDetail>(sql);
                if (DispatchDetail.Count > 0)
                {
                    AjaxResult res = new AjaxResult
                    {
                        Success = false,
                        Msg = "任务单有派工不能作废！"
                    };

                    return res;
                }
                else
                {
                    Return = await ExecuteSqlAsync("UPDATE  PB_ProductionOrder set Status=3    where Id='" + idIn + "';");//作废
                }
            }
            if (Return > 0)
            {
                AjaxResult res = new AjaxResult
                {
                    Success = true,
                    Msg = "请求成功！"
                };

                return res;
            }
            else
            {
                AjaxResult res = new AjaxResult
                {
                    Success = false,
                    Msg = "提交数据有误！"
                };

                return res;
            }
        }


        public async Task<PB_ProductionOrderList> GetPDADataListInfo(string cateqrcode)
        {
            string[] qrcodemodel = cateqrcode.Split(',');
            string juber = qrcodemodel[0].ToString();
            if (juber != "02" || juber != "03")
            {
                if (qrcodemodel.Length == 3) // 单个物料
                {
                    PB_ProductionOrderList pblist = new PB_ProductionOrderList();
                    Expression<Func<PB_ProductionOrder, PB_DesignList, Entity.PB.PB_ProductionOrderDTO>> selects = (a, b) => new Entity.PB.PB_ProductionOrderDTO
                    {
                        DLName = b.Name
                    };
                    selects = selects.BuildExtendSelectExpre();
                    var qdata = from a in Db.GetIQueryable<PB_ProductionOrder>().AsExpandable()
                                join b in Db.GetIQueryable<PB_DesignList>() on a.DesignId equals b.Id into ab
                                from b in ab.DefaultIfEmpty()
                                select @selects.Invoke(a, b);
                    pblist.mainData = await qdata.Where(x => x.Id == qrcodemodel[1].ToString()).FirstOrDefaultAsync();
                    Expression<Func<PB_ProductionOrderDetail, PB_Material, PB_MaterialType, Base_UnitItems, Entity.PB.PB_ProductionOrderDetailDTO>> select = (a, b, c, d) => new Entity.PB.PB_ProductionOrderDetailDTO
                    {

                        MaterialID = b.Id,//物料编号
                        MaterialName = b.Name,//物料名称
                        MaterialTypeId = c.Name,//类型名称
                        MaterialCode = b.Code,//物料编号
                        PackingSpec = b.Spec, //物料规格
                        Weight = b.Weight,//理论重量
                        UnitGroupName = d.Name,
                    };
                    select = select.BuildExtendSelectExpre();
                    var q = from a in Db.GetIQueryable<PB_ProductionOrderDetail>().AsExpandable()
                            join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                            from b in ab.DefaultIfEmpty()
                            join c in Db.GetIQueryable<PB_MaterialType>() on b.MaterialTypeId equals c.Id into ac
                            from c in ac.DefaultIfEmpty()
                            join d in Db.GetIQueryable<Base_UnitItems>() on b.storageId equals d.Id into ad
                            from d in ad.DefaultIfEmpty()
                            select @select.Invoke(a, b, c, d);
                    q = q.Where(x => x.Id == qrcodemodel[2].ToString());
                    pblist.subData = await q.ToListAsync();
                    return pblist;
                }
                else  //多个物料
                {
                    PB_ProductionOrderList pblist = new PB_ProductionOrderList();
                    Expression<Func<PB_ProductionOrder, PB_DesignList, Entity.PB.PB_ProductionOrderDTO>> selects = (a, b) => new Entity.PB.PB_ProductionOrderDTO
                    {
                        DLName = b.Name
                    };
                    selects = selects.BuildExtendSelectExpre();
                    var qdata = from a in Db.GetIQueryable<PB_ProductionOrder>().AsExpandable()
                                join b in Db.GetIQueryable<PB_DesignList>() on a.DesignId equals b.Id into ab
                                from b in ab.DefaultIfEmpty()
                                select @selects.Invoke(a, b);
                    pblist.mainData = await qdata.Where(x => x.Id == qrcodemodel[1].ToString()).FirstOrDefaultAsync();
                    Expression<Func<PB_ProductionOrderDetail, PB_Material, PB_MaterialType, Base_UnitItems, Entity.PB.PB_ProductionOrderDetailDTO>> select = (a, b, c, d) => new Entity.PB.PB_ProductionOrderDetailDTO
                    {

                        MaterialID = b.Id,//物料编号
                        MaterialName = b.Name,//物料名称
                        MaterialTypeId = c.Name,//类型名称
                        MaterialCode = b.Code,//物料编号
                        PackingSpec = b.Spec, //物料规格
                        Weight = b.Weight,//理论重量
                        UnitGroupName = d.Name,
                    };
                    select = select.BuildExtendSelectExpre();
                    var q = from a in Db.GetIQueryable<PB_ProductionOrderDetail>().AsExpandable()
                            join b in Db.GetIQueryable<PB_Material>() on a.MaterialId equals b.Id into ab
                            from b in ab.DefaultIfEmpty()
                            join c in Db.GetIQueryable<PB_MaterialType>() on b.MaterialTypeId equals c.Id into ac
                            from c in ac.DefaultIfEmpty()
                            join d in Db.GetIQueryable<Base_UnitItems>() on b.storageId equals d.Id into ad
                            from d in ad.DefaultIfEmpty()
                            select @select.Invoke(a, b, c, d);
                    q = q.Where(x => x.ParentId == qrcodemodel[1].ToString());
                    pblist.subData = await q.ToListAsync();
                    return pblist;
                }
            }
            else
            {
                throw new BusException("请扫描或输入正确的生产任务单二维码信息");
            }



        }
        [Transactional]
        public async Task AddPDADataAsync(TD_OutStorage data)
        {

            if (data.Code.IsNullOrEmpty())
            {
                data.Code = DateTime.Now.ToString("yyyyMMddHHmmss");
            }
            var detpdata = await _opdept.GetOperatorDept();
            TD_OutStorage tD_OutStorage = new TD_OutStorage();
            tD_OutStorage.Id = data.Id;
            tD_OutStorage.Code = data.Code;
            tD_OutStorage.StorageId = data.StorageId;
            tD_OutStorage.OutTime = DateTime.Now;
            tD_OutStorage.OutType = "ProductOut";
            tD_OutStorage.RefCode = data.RefCode;
            tD_OutStorage.OutNum = data.OutStorDetails.Sum(s => s.OutNum);
            tD_OutStorage.TotalAmt = data.OutStorDetails.Sum(s => s.TotalAmt);
            tD_OutStorage.Status = 0;
            tD_OutStorage.CusId = data.CusId;
            tD_OutStorage.Address = data.Address;
            tD_OutStorage.Remarks = data.Remarks;
            tD_OutStorage.CreatorId = data.CreatorId;
            tD_OutStorage.CreateTime = DateTime.Now;
            tD_OutStorage.Deleted = false;
            tD_OutStorage.DepId = data.DepId;
            await Db.InsertAsync<TD_OutStorage>(tD_OutStorage);
            List<TD_OutStorDetail> tD_OutStorDetaillist = new List<TD_OutStorDetail>();
            foreach (var item in data.OutStorDetails)
            {
                TD_OutStorDetail tD_OutStorDetail = new TD_OutStorDetail();
                tD_OutStorDetail.Id = IdHelper.GetId();
                tD_OutStorDetail.StorId = item.StorId;  //仓库ID
                tD_OutStorDetail.OutStorId = data.Id;  // 出库ID 
                tD_OutStorDetail.LocalId = item.LocalId;
                tD_OutStorDetail.AreaId = item.AreaId;
                tD_OutStorDetail.RackId = item.RackId;
                tD_OutStorDetail.BarCode = item.BarCode;
                tD_OutStorDetail.MaterialId = item.MaterialId;
                //tD_OutStorDetail.BatchNo = item.BatchNo;
                tD_OutStorDetail.Price = item.Price;
                tD_OutStorDetail.TotalAmt = item.TotalAmt;
                tD_OutStorDetail.LocalNum = item.LocalNum;
                tD_OutStorDetail.OutNum = item.OutNum;
                tD_OutStorDetail.CreateTime = DateTime.Now;
                tD_OutStorDetail.CreatorId = data.CreatorId;
                tD_OutStorDetail.Deleted = false;
                tD_OutStorDetaillist.Add(tD_OutStorDetail);
            }
            await Db.InsertAsync<TD_OutStorDetail>(tD_OutStorDetaillist);
            List<TD_OutStorRecord> tD_OutStorRecordlist = new List<TD_OutStorRecord>();
            var list = data.OutStorDetails.GroupBy(s => new { s.MaterialId, s.Price, s.StorId }).Select(x => new { MaterialId = x.Key.MaterialId, Price = x.Key.Price, StorId = x.Key.StorId, Num = x.Sum(i => i.OutNum), TotalAmt = x.Sum(i => i.TotalAmt) });
            foreach (var item in list)
            {
                TD_OutStorRecord tD_OutStorRecord = new TD_OutStorRecord();
                tD_OutStorRecord.Id = IdHelper.GetId();
                tD_OutStorRecord.StorId = item.StorId;
                tD_OutStorRecord.OutStorId = data.Id;
                tD_OutStorRecord.MaterialId = item.MaterialId;
                tD_OutStorRecord.Price = item.Price;
                tD_OutStorRecord.TotalAmt = item.TotalAmt;
                tD_OutStorRecord.OutNum = item.Num;
                tD_OutStorRecord.CreateTime = DateTime.Now;
                tD_OutStorRecord.CreatorId = data.CreatorId;
                tD_OutStorRecord.Deleted = false;
                tD_OutStorRecordlist.Add(tD_OutStorRecord);
            }
            await Db.InsertAsync<TD_OutStorRecord>(tD_OutStorRecordlist);

        }

        /// <summary>
        /// 生产任务单根据设计清单选择物料（明细汇总）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<DesignMaterialDTO>> GetDesignMaterialListAsync(PageInput<DesignMaterialConditionDTO> input)
        {
            var search = input.Search;
            string sqlMain = @"select *,case when ProductionOrNot=1 then RealNums-CompleteNums else 0 end as SurplusProduction from (
select *,case when (ScanNum-Nums_R)>0 then (ScanNum-Nums_R) else 0 end as AvailableQuantity,IFNULL((select SUM(OI.CompleteNums) AS CompleteNums from PB_ProductionOrder as O left join PB_ProductionOrderDetail as OI on O.Id=OI.ParentId where O.DesignId=t3.ParentId and OI.MaterialId=t3.Id  ),0) as CompleteNums,case when (ScanNum-Nums_R)>=RealNums then 0 else 1 end as ProductionOrNot from (
select ParentId,MaterialId as Id,`Name`,`Code`,Spec,ProductCode,Nums,RealNums,UsageStatus,UnitGroupId,UnitGroupName,PackageNum,IFNULL(SUM(ScanNum),0) as ScanNum,IFNULL(SUM(Nums_R),0) as Nums_R from (
select t.*,a.`Name`,a.`Code`,a.Spec,a.ProductCode,b.ScanNum,b.Nums_R,a.UsageStatus,a.UnitGroupId,c.`Name` as UnitGroupName,a.PackageNum from (
select ParentId,MaterialId,SUM(Nums) as Nums,SUM(RealNums) as RealNums from (
select ParentId,MaterialId,Nums,RealNums from PB_DesignDetail where State!=2 and ParentId='" + search.DesignId + "' UNION ALL select ParentId,MaterialId,-Nums,-RealNums from PB_DesignDetail where State=2 and ParentId= '" + search.DesignId + "' ) as tb group by ParentId,MaterialId ) as t  left join PB_Material as a on t.MaterialId=a.Id left join IT_LocalMaterial as b on t.MaterialId=b.MaterialId left join Base_UnitGroup as c on a.UnitGroupId=c.Id ) as t1 group by ParentId,MaterialId,`Name`,`Code`,Spec,ProductCode,Nums,RealNums,UsageStatus )as t3 )as t4 where 1=1";
            if (search.IsProduction == 1)
            {
                sqlMain += @" and ProductionOrNot=1 ";
            }
            else if (search.IsProduction == 0) {
                sqlMain += @" and ProductionOrNot=0 ";
            }
            if (!search.Keyword.IsNullOrEmpty())
            {
                sqlMain += @" and (`Name` like '%" + search.Keyword + "%' or `Code` like '%" + search.Keyword + "%' or ProductCode like '%" + search.Keyword + "%' or Spec like '%" + search.Keyword + "%') ";
            }
            if (!search.UnitGroupId.IsNullOrEmpty()) {
                sqlMain += "and UnitGroupId='"+input.Search.UnitGroupId+"'";
            }
            var lidata = await Db.GetListBySqlAsync<DesignMaterialDTO>(sqlMain);
            int num = lidata.Count;
            var list = lidata
               .Skip((input.PageIndex - 1) * input.PageRows)
               .Take(input.PageRows).ToList();
            return new PageResult<DesignMaterialDTO> { Data = list, Total = num };

        }

        /// <summary>
        /// 生产任务单根据设计清单选择物料（明细）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<DesignMaterialDTO>> GetDesignMaterialDetailListAsync(PageInput<DesignMaterialConditionDTO> input)
        {
            var search = input.Search;
            string sqlMain = string.Empty;
            if (search.State == 0)
            {
                sqlMain = @"select *,case when ProductionOrNot=1 then RealNums-CompleteNums else 0 end as SurplusProduction from (
select *,case when (ScanNum-Nums_R)>0 then (ScanNum-Nums_R) else 0 end as AvailableQuantity,IFNULL((select SUM(OI.CompleteNums) AS CompleteNums from PB_ProductionOrder as O left join PB_ProductionOrderDetail as OI on O.Id=OI.ParentId where O.DesignId=t.ParentId and OI.MaterialId=t.Id  ),0) as CompleteNums,case when (ScanNum-Nums_R)>=RealNums then 0 else 1 end as ProductionOrNot from (
select a.Id DetailId, a.MaterialId as Id,a.ParentId,b.`Name`,b.`Code`,b.Spec,b.ProductCode,a.Slot,a.State,a.Nums,a.RealNums,b.UsageStatus,b.UnitGroupId,d.`Name` as UnitGroupName,SUM(IFNULL(c.ScanNum,0)) as ScanNum,SUM(IFNULL(c.Nums_R,0)) as Nums_R,b.PackageNum from PB_DesignDetail as a 
left join PB_Material as b on a.MaterialId=b.Id
left join IT_LocalMaterial as c on a.MaterialId=c.MaterialId
left join Base_UnitGroup as d on b.UnitGroupId=d.Id
where a.ParentId='" + search.DesignId + "' group by  a.Id,a.MaterialId,a.ParentId,b.`Name`,b.`Code`,b.Spec,b.ProductCode,a.Nums,a.RealNums,b.UsageStatus,a.Slot,a.State,b.UnitGroupId,d.`Name` order by a.Id  ) as t ) as t1 where State='" + search.State + "' ";

            }
            else
            {
                sqlMain = @"select *,case when ProductionOrNot=1 then RealNums-CompleteNums else 0 end as SurplusProduction,'{0}' as State from (
select *,case when (ScanNum-Nums_R)>0 then (ScanNum-Nums_R) else 0 end as AvailableQuantity,
IFNULL((select SUM(OI.CompleteNums) AS CompleteNums 
from PB_ProductionOrder as O left join PB_ProductionOrderDetail as OI on O.Id=OI.ParentId where O.DesignId=t.ParentId and OI.MaterialId=t.Id  ),0) as CompleteNums,case when (ScanNum-Nums_R)>=RealNums then 0 else 1 end as ProductionOrNot from (
select a.Id,a.ParentId,b.`Name`,b.`Code`,b.Spec,b.ProductCode,a.Nums,a.RealNums,b.UsageStatus,b.UnitGroupId,d.`Name` as UnitGroupName,SUM(IFNULL(c.ScanNum,0)) as ScanNum,SUM(IFNULL(c.Nums_R,0)) as Nums_R,a.Slot,b.PackageNum  from (
select des.MaterialId as Id,des.ParentId,SUM(des.Nums) as Nums,SUM(des.RealNums) as RealNums,(select Id from PB_DesignDetail where State={0} and ParentId='{1}' and MaterialId=des.MaterialId order by Id LIMIT 1) as Slot from PB_DesignDetail as des where des.State={0} and des.ParentId='{1}' group by des.MaterialId,des.ParentId  
)as a 
left join PB_Material as b on a.Id=b.Id 
left join IT_LocalMaterial as c on a.Id=c.MaterialId 
left join Base_UnitGroup as d on b.UnitGroupId=d.Id 
group by a.Id,a.ParentId,b.`Name`,b.`Code`,b.Spec,b.ProductCode,a.Nums,a.RealNums,b.UsageStatus,a.Slot,b.UnitGroupId,d.`Name`  order by a.Slot
)as t 
) as t1 where 1=1  ";
                sqlMain = string.Format(sqlMain, search.State, search.DesignId);
            }
            if (search.IsProduction == 1)
            {
                sqlMain += @" and ProductionOrNot=1 ";
            }
            if (!search.Keyword.IsNullOrEmpty())
            {
                sqlMain += @"  and (`Name` like '%" + search.Keyword + "%' or `Code` like '%" + search.Keyword + "%' or ProductCode like '%" + search.Keyword + "%'  or Spec like '%" + search.Keyword + "%') ";
            }
            if (!search.UnitGroupId.IsNullOrEmpty()) {
                sqlMain += " AND  UnitGroupId='"+input.Search.UnitGroupId+"'";
            }
            var lidata = await Db.GetListBySqlAsync<DesignMaterialDTO>(sqlMain);
            int num = lidata.Count;
            var list = lidata
               .Skip((input.PageIndex - 1) * input.PageRows)
               .Take(input.PageRows).ToList();
            return new PageResult<DesignMaterialDTO> { Data = list, Total = num };
        }


        //Task<PageResult<Entity.DTO.PB_ProductionOrderDTO>> IPB_ProductionOrderBusiness.GetDataListShowDeptNameAsync(PageInput<Entity.DTO.PB_ProductionOrderConditionDTO> input)
        //{
        //    throw new NotImplementedException();
        //}
        /// <summary>
        /// 获取任务单名称
        /// </summary>
        /// <param name="WorkShop"></param>
        /// <returns></returns>
        public async Task<List<Entity.DTO.ProductionPlanWorkShop>> GetProductionPlanWorkShop(string WorkShop)
        {
            //
            var ITEM = await GetPollToGetTaskList();

            var res = new List<Entity.DTO.ProductionPlanWorkShop>();
            //取得生产计划名称
            string strSQL = @"SELECT po.Id,po.POName,po.BeginDate,po.EndDate FROM PB_ProductionOrder po WHERE po.Id='" + ITEM.Id + "' ORDER BY po.BeginDate DESC";
            var temp = Db.GetListBySql<PB_ProductionOrder>(strSQL);
            string TasckId = "";
            string TasckName = "";
            temp.ForEach(aData =>
            {

                Entity.DTO.ProductionPlanWorkShop item = new Entity.DTO.ProductionPlanWorkShop();
                item.Id = ITEM.Id;

                item.POName = new Entity.DTO.ScreenDisplayValue3DTO { value = ITEM.POName.Trim() };
                if (aData.BeginDate != null)
                {
                    item.StartDate = new Entity.DTO.ScreenDisplayValue3DTO { value = Convert.ToDateTime(aData.BeginDate).ToString("MM月dd日") };
                }
                if (aData.EndDate != null)
                {
                    item.EndDate = new Entity.DTO.ScreenDisplayValue3DTO { value = Convert.ToDateTime(aData.EndDate).ToString("MM月dd日") };
                }



                res.Add(item);
            });

            return res;

        }

        /// <summary>
        /// 获取进度
        /// </summary>
        /// <param name="WorkShop"></param>
        /// <returns></returns>
        public async Task<List<Entity.DTO.GetPassRate>> Gethege(string WorkShop)
        {
            var Item = await GetPollToGetTaskListTrue();
            var res = new List<Entity.DTO.GetPassRate>();
            Entity.DTO.GetPassRate item = new Entity.DTO.GetPassRate();

            //取得生产计划目前进度
            string strSQL = @"SELECT '目前进度' AS label,
IF(SUM(plan.PlanNums) IS NULL OR SUM(plan.PlanNums)=0,0,IF(IFNULL(SUM(finish.ReturnNums),0)>SUM(plan.PlanNums),100,IFNULL(SUM(finish.ReturnNums),0)/SUM(plan.PlanNums)*100)) AS value,
IF(SUM(plan.PlanNums) IS NULL OR SUM(plan.PlanNums)=0,0,IF(IFNULL(SUM(finish.ReturnNums),0)>SUM(plan.PlanNums),100,IFNULL(SUM(finish.ReturnNums),0)/SUM(plan.PlanNums)*100)) AS data
FROM
(SELECT ParentId,IFNULL(SUM(pd.Productionquantity),0) AS PlanNums
FROM PB_ProductionOrderDetail pd
WHERE ParentId='" + Item.Id + @"') plan
JOIN 
(SELECT a.poId,IFNULL(SUM(a.ReturnNums),0) AS ReturnNums
FROM
(SELECT jb.Id AS jbId,po.Id AS poId,IFNULL(jb.ReturnNums,0) AS ReturnNums
FROM PB_JobBooking jb
JOIN PB_CirculationBill cb ON jb.CirBillId=cb.Id 
JOIN PB_Dispatch dp ON cb.DispatchId=dp.Id
JOIN PB_DispatchDetail dd ON dd.ParentId=dp.Id
JOIN PB_ProductionOrder po ON dd.OrderId=po.Id AND po.Id='" + Item.Id + @"'
UNION
SELECT jb.Id AS jbId,po.Id AS poId,IFNULL(jb.ReturnNums,0) AS ReturnNums
FROM PB_JobBooking jb
JOIN PB_CirculationBill cb ON jb.CirBillId=cb.Id
JOIN PB_ProductionOrder po ON cb.TaskId=po.Id AND po.Id='" + Item.Id + @"') a
GROUP BY a.poId) finish
ON plan.ParentId=finish.poId";
            item.CurProgress = Db.GetListBySqlAsync<Entity.DTO.ScreenDisplayProgressDTO>(strSQL).Result.FirstOrDefault();
            item.CurProgress.value = Convert.ToDecimal(item.CurProgress.value.ToString("#0.##"));
            item.CurProgress.data = Convert.ToDecimal(item.CurProgress.data.ToString("#0.##"));

            res.Add(item);
            return res;
        }
        /// <summary>
        /// 获取整体合格率
        /// </summary>
        /// <param name="WorkShop"></param>
        /// <returns></returns>
        public async Task<List<Entity.DTO.OverallQualificationRate>> GerProjectRate(string WorkShop)
        {
            var res = new List<Entity.DTO.OverallQualificationRate>();
            //取得生产计划名称
            Entity.DTO.ProductionPlanWorkShop items = new Entity.DTO.ProductionPlanWorkShop();
            Entity.DTO.OverallQualificationRate item = new Entity.DTO.OverallQualificationRate();
            Entity.DTO.WorkReportlist workReportlist = new Entity.DTO.WorkReportlist();
            var ITEM = await GetPollToGetTaskListTrue();
            //取得生产计划按物料统计的计划数、报工数、不合格数和入库数
            string strSQL = @"SELECT
plan.MaterialId,m.`Name` AS mmname,m.ProductCode AS productcode,IFNULL(SUM(plan.plannum),0) AS plannum,IFNULL(SUM(finish.producenum),0) AS producenum,IFNULL(SUM(finish.unqualifinum),0) AS unqualifinum,IFNULL(SUM(finish.checkin),0) AS checkin,
IF(SUM(finish.producenum) IS NULL OR SUM(finish.producenum)=0,0,IF(IFNULL(SUM(finish.ReturnNums),0)>SUM(finish.producenum),100,IFNULL(SUM(finish.ReturnNums),0)/SUM(finish.producenum)*100)) AS QualiRate
FROM
(SELECT pd.MaterialId,SUM(pd.Productionquantity) AS plannum
FROM PB_ProductionOrderDetail pd
JOIN PB_Material pm ON pd.MaterialId=pm.Id
WHERE ParentId='" + ITEM.Id + @"'
GROUP BY pd.MaterialId) plan
JOIN PB_Material m ON plan.MaterialId=m.Id
LEFT JOIN 
(SELECT a.MaterialId,IFNULL(SUM(a.Nums),0) AS producenum,IFNULL(SUM(a.Nums),0)-IFNULL(SUM(a.ReturnNums),0) AS unqualifinum,IFNULL(SUM(a.ReturnNums),0) AS ReturnNums,IFNULL(SUM(a.checkin),0) AS checkin
FROM
(SELECT jb.Id AS jbId,jb.MaterialId,jb.Nums,po.Id AS poId,IFNULL(jb.ReturnNums,0) AS ReturnNums,jb.StatisticsNums AS checkin
FROM PB_JobBooking jb
JOIN PB_CirculationBill cb ON jb.CirBillId=cb.Id 
JOIN PB_Dispatch dp ON cb.DispatchId=dp.Id
JOIN PB_DispatchDetail dd ON dd.ParentId=dp.Id
JOIN PB_ProductionOrder po ON dd.OrderId=po.Id AND po.Id='" + ITEM.Id + @"'
UNION
SELECT jb.Id AS jbId,jb.MaterialId,jb.Nums,po.Id AS poId,IFNULL(jb.ReturnNums,0) AS ReturnNums,jb.StatisticsNums AS checkin
FROM PB_JobBooking jb
JOIN PB_CirculationBill cb ON jb.CirBillId=cb.Id
JOIN PB_ProductionOrder po ON cb.TaskId=po.Id AND po.Id='" + ITEM.Id + @"') a
GROUP BY a.MaterialId) finish
ON plan.MaterialId=finish.MaterialId
GROUP BY plan.MaterialId";
            workReportlist.BookingByMaterial = Db.GetListBySqlAsync<Entity.DTO.BookingDetailByMaterialDTO>(strSQL).Result;
            double sumQualiRate = 0;
            workReportlist.BookingByMaterial.ForEach(bData =>
            {
                sumQualiRate += bData.QualiRate;
            });
            if (workReportlist.BookingByMaterial.Count > 0)
            {
                item.QualifiedRate = new Entity.DTO.ScreenDisplayDashboardDTO { value = Convert.ToDecimal((sumQualiRate / workReportlist.BookingByMaterial.Count).ToString("#0.##")) };
            }
            else
            {
                item.QualifiedRate = new Entity.DTO.ScreenDisplayDashboardDTO { value = 0 };
            }

            res.Add(item);
            return res;
        }

        /// <summary>
        /// 获取报工列表
        /// </summary>
        /// <param name="WorkShop"></param>
        /// <returns></returns>
        public async Task<List<Entity.DTO.WorkReportlist>> GetWorkReportlist(string WorkShop)
        {
            var res = new List<Entity.DTO.WorkReportlist>();
            Entity.DTO.ProductionPlanWorkShop items = new Entity.DTO.ProductionPlanWorkShop();
            Entity.DTO.OverallQualificationRate item = new Entity.DTO.OverallQualificationRate();
            Entity.DTO.WorkReportlist workReportlist = new Entity.DTO.WorkReportlist();
            var ITEM = await GetPollToGetTaskListTrue();
            //取得生产计划按物料统计的计划数、报工数、不合格数和入库数
            string strSQL = @"SELECT t.*,IFNULL( y.Nums, 0 ) producenum,IFNULL(y.StatisticsNums,0) StatisticsNums,IFNULL( t.InNums, 0 ) checkin,CASE
		WHEN dispatchDetail.State > 0 THEN '已派工' ELSE '未派工' END State,CASE WHEN IFNULL( t.InNums, 0 ) > 0 THEN  '已生产' WHEN dispatchDetail.State > 0 THEN '生产中'  else '未生产'  END ProductionStatus ,CASE WHEN IFNULL( y.StatisticsNums, 0 ) = 0 THEN	0 ELSE IFNULL( y.Nums, 0 )-IFNULL(y.StatisticsNums,0) END unqualifinum FROM (SELECT a.Id,b.`Name` mmname,a.MaterialId,	b.ProductCode productcode,a.Productionquantity plannum, a.CompleteNums InNums,IFNULL(a.Productionquantity*b.Weight,0) PlannedWeight FROM
		PB_ProductionOrderDetail AS a	LEFT JOIN PB_Material AS b ON a.MaterialId = b.Id 	WHERE a.ParentId = '" + ITEM.Id + "' ) AS t LEFT JOIN ( SELECT IFNULL( SUM( a.Nums ), 0 ) Nums,	IFNULL(sum(a.StatisticsNums),0) StatisticsNums,b.TaskDetailId,a.MaterialId FROM	PB_JobBooking AS a 	LEFT JOIN PB_CirculationBill AS b ON a.CirBillId = b.Id  GROUP BY 	b.TaskDetailId,	a.MaterialId ) AS y ON t.Id = y.TaskDetailId LEFT JOIN ( SELECT IFNULL( count( Id ), 0 ) State, OrderDetailId FROM PB_DispatchDetail GROUP BY OrderDetailId ) AS dispatchDetail ON dispatchDetail.OrderDetailId = t.Id";
            workReportlist.BookingByMaterial = Db.GetListBySqlAsync<Entity.DTO.BookingDetailByMaterialDTO>(strSQL).Result;
            double sumQualiRate = 0;
            workReportlist.BookingByMaterial.ForEach(bData =>
            {
                sumQualiRate += bData.QualiRate;
            });
            if (workReportlist.BookingByMaterial.Count > 0)
            {
                item.QualifiedRate = new Entity.DTO.ScreenDisplayDashboardDTO { value = Convert.ToDecimal((sumQualiRate / workReportlist.BookingByMaterial.Count).ToString("#0.##")) };
            }
            else
            {
                item.QualifiedRate = new Entity.DTO.ScreenDisplayDashboardDTO { value = 0 };
            }
            res.Add(workReportlist);

            return res;
        }

        /// <summary>
        /// 获取报工人
        /// </summary>
        /// <param name="WorkShop"></param>
        /// <returns></returns>
        public async Task<List<Entity.DTO.Statisticaldata>> GetStatisticaldata(string WorkShop)
        {
            var res = new List<Entity.DTO.Statisticaldata>();
            Entity.DTO.ProductionPlanWorkShop items = new Entity.DTO.ProductionPlanWorkShop();
            Entity.DTO.Statisticaldata statisticaldata = new Entity.DTO.Statisticaldata();
            //取得生产计划名称
            var ITEM = await GetPollToGetTaskListTrue();

            //取得生产计划的报工人数、件数和总重量
            string strSQL = @"SELECT
	 IFNULL(CirculationBill.UserNums,0) UserNums,
  IFNULL(SUM( JobBooking.StatisticsNums),0) 	 StatisticsNums,
	IFNULL(SUM(JobBooking.StatisticsWeight),0) StatisticsWeight
FROM
	(
	SELECT  DISTINCT
	po.Id,
  IFNULL(sum(a.Nums),0) 'StatisticsNums',
  round(IFNULL( SUM( a.Nums ), 0 ) * IFNULL( SUM( m.Weight ), 0 ),4)  'StatisticsWeight'
FROM
PB_JobBooking AS a
LEFT JOIN PB_CirculationBill as b on a.CirBillId=b.Id
LEFT JOIN PB_ProductionOrderDetail as detail on b.TaskDetailId=detail.Id
left JOIN PB_ProductionOrder po ON detail.ParentId = po.Id 
 
left JOIN PB_Material as m on a.MaterialId=m.Id		
WHERE po.Id = '" + ITEM.Id + "'		) AS  JobBooking	LEFT JOIN( select Count(pp.ReportUserId)'UserNums', pp.Id  FROM (select tt.ReportUserId,tt.Id from (SELECT DISTINCT jb.WorkerId AS ReportUserId ,po.Id FROM PB_CirculationBill jb 	JOIN PB_ProductionOrder po ON jb.TaskId = po.Id JOIN PB_Material m ON jb.MaterialId = m.Id AND po.Id = '" + ITEM.Id + "' GROUP BY jb.WorkerId UNION ALL SELECT DISTINCT a.ReportUserId  AS  ReportUserId,po.Id FROM PB_JobBooking AS a LEFT JOIN PB_CirculationBill AS b ON a.CirBillId = b.Id LEFT JOIN PB_ProductionOrderDetail AS detail ON b.TaskDetailId = detail.Id LEFT JOIN PB_ProductionOrder po ON detail.ParentId = po.Id LEFT JOIN PB_Material AS m ON a.MaterialId = m.Id  WHERE po.Id = '" + ITEM.Id + "' ) AS tt GROUP BY tt.ReportUserId,tt.Id) AS pp GROUP BY pp.Id) AS CirculationBill ON CirculationBill.Id = JobBooking.Id  GROUP BY  CirculationBill.UserNums";
            Entity.DTO.PB_ProductionOrderStatisDTO block = Db.GetListBySqlAsync<Entity.DTO.PB_ProductionOrderStatisDTO>(strSQL).Result.FirstOrDefault();
            Entity.DTO.ScreenDisplayColorBlockDetailDTO UserNums = new Entity.DTO.ScreenDisplayColorBlockDetailDTO { backgroundColor = "#67C23A", prefixText = "报工人数", value = block.UserNums.ToString("#0.##"), suffixText = "人" };
            Entity.DTO.ScreenDisplayColorBlockDetailDTO StatisticsNums = new Entity.DTO.ScreenDisplayColorBlockDetailDTO { backgroundColor = "#409EFF", prefixText = "总件数", value = block.StatisticsNums.ToString("#0.##"), suffixText = "件" };
            Entity.DTO.ScreenDisplayColorBlockDetailDTO StatisticsWeight = new Entity.DTO.ScreenDisplayColorBlockDetailDTO { backgroundColor = "#E6A23C", prefixText = "总吨数", value = block.StatisticsWeight.ToString("#0.##"), suffixText = "吨" };
            statisticaldata.Statistics = new Entity.DTO.ScreenDisplayColorBlockDTO();
            statisticaldata.Statistics.list.Add(UserNums);
            statisticaldata.Statistics.list.Add(StatisticsNums);
            statisticaldata.Statistics.list.Add(StatisticsWeight);
            res.Add(statisticaldata);
            return res;
        }


        /// <summary>
        /// 获取任务单数据
        /// </summary>
        /// <returns></returns>
        public async Task<PollToGetTaskList> GetPollToGetTaskList() {

            PollToGetTaskList pollToGetTaskList = new PollToGetTaskList();
            string sql = "select * from  PB_TaskOrder";
            string sqlmain = "select c.Id,c.POName,c.BeginDate,c.EndDate from  PB_JobBooking as a INNER JOIN PB_ProductionOrderDetail AS b on a.ParentId = b.Id INNER JOIN PB_ProductionOrder AS c on b.ParentId = c.Id where DATE_SUB(CURDATE(), INTERVAL 2 DAY) <= date(a.ReportTime) GROUP BY c.Id,c.POName ";
            var sqllist = await Db.GetListBySqlAsync<PB_TaskOrder>(sql.ToString());
            var ProductionOrderlist = await Db.GetListBySqlAsync<PB_ProductionOrder>(sqlmain.ToString());
            if (sqllist.Count == 0)
            {
                string Id = IdHelper.GetId();
                string Insert = $"INSERT INTO `PB_TaskOrder`(`Id`, `TaskOrderID`, `TaskName`, `Index`) VALUES ('{Id}', '{ProductionOrderlist[0].Id}', '{ProductionOrderlist[0].POName}', 0);";
                await ExecuteSqlAsync(Insert);
                pollToGetTaskList.Id = sqllist[0].TaskOrderID;
                pollToGetTaskList.POName = sqllist[0].TaskName;
                pollToGetTaskList.Index = 0;
            }
            else
            {
                int _idx = 0;//当前索引
                if (sqllist[0].Index + 1 < ProductionOrderlist.Count)
                {
                    _idx = Convert.ToInt32(sqllist[0].Index) + 1;
                }
                string Update = $"UPDATE `PB_TaskOrder` SET `TaskOrderID` = '{ProductionOrderlist[_idx].Id}', `TaskName` = '{ProductionOrderlist[_idx].POName}', `Index` = " + _idx;
                await ExecuteSqlAsync(Update);
                pollToGetTaskList.Id = ProductionOrderlist[_idx].Id;
                pollToGetTaskList.POName = ProductionOrderlist[_idx].POName;
                pollToGetTaskList.Index = _idx;
            }
            //else if (sqllist[0].Index+1== ProductionOrderlist.Count()) {
            //    string Update = $"UPDATE `PB_TaskOrder` SET `TaskOrderID` = '{ProductionOrderlist[0].Id}', `TaskName` = '{ProductionOrderlist[0].POName}', `Index` = 0 ;";
            //    await ExecuteSqlAsync(Update);
            //}
            //else {
            //    int index = 0;
            //    if (index < ProductionOrderlist.Count - 1) {
            //        index++;
            //        string Update = $"UPDATE `PB_TaskOrder` SET `TaskOrderID` = '{ProductionOrderlist[index].Id}', `TaskName` = '{ProductionOrderlist[index].POName}', `Index` = Index+{index} ;";
            //        await ExecuteSqlAsync(Update);
            //        pollToGetTaskList.Id = sqllist[index].TaskOrderID;
            //        pollToGetTaskList.POName = sqllist[index].TaskName;
            //        pollToGetTaskList.Index = sqllist[index].Index;
            //    }
            //}
            return pollToGetTaskList;
        }
        public async Task<PollToGetTaskList> GetPollToGetTaskListTrue()
        {

            PollToGetTaskList pollToGetTaskList = new PollToGetTaskList();
            string sql = "select * from  PB_TaskOrder";
            string sqlmain = "SELECT po.Id,po.POName,po.BeginDate,po.EndDate FROM PB_ProductionOrder po JOIN Base_Department d ON po.Status = 1 AND po.IsRefurbishment = 1 AND po.DeptId = d.Id  ORDER BY po.BeginDate DESC limit 1";
            var sqllist = await Db.GetListBySqlAsync<PB_TaskOrder>(sql.ToString());
            var ProductionOrderlist = await Db.GetListBySqlAsync<PB_ProductionOrder>(sqlmain.ToString());

            pollToGetTaskList.Id = sqllist[0].TaskOrderID;
            pollToGetTaskList.POName = sqllist[0].TaskName;
            pollToGetTaskList.Index = sqllist[0].Index;


            return pollToGetTaskList;
        }
        #endregion


        #region   组件生产任务单

        /// <summary>
        /// 获取需要组件的BOM物料信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<BomMaterialDTO>> GetBomMaterialListAsync(PageInput<OrderBomMaterialConditionDTO> input)
        {
            var search = input.Search;
            var where = LinqHelper.True<BomMaterialDTO>();
            Expression<Func<Bom_MainNode, PB_Material, Base_UnitGroup, BomMaterialDTO>> select = (a, b, c) => new BomMaterialDTO
            {
                Id = a.MaterailId,
                Name = b.Name,
                Code = b.Code,
                Spec = b.Spec,
                ProductCode = b.ProductCode,
                UnitGroupName = c.Name
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in Db.GetIQueryable<Bom_MainNode>().AsExpandable()
                    join b in Db.GetIQueryable<PB_Material>() on a.MaterailId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_UnitGroup>() on b.UnitGroupId equals c.Id into bc
                    from c in bc.DefaultIfEmpty()
                    select @select.Invoke(a, b, c);
            if (!search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<BomMaterialDTO, bool>(
                   ParsingConfig.Default, false, $@"Code.Contains(@0) or Name.Contains(@0) or Spec.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }
            if (!search.ProductCode.IsNullOrEmpty())
            {
                q = q.Where(x => x.ProductCode == search.ProductCode);
            }
            return await q.Where(where).GetPageResultAsync(input);
        }

        #endregion

        #region 生产任务单明细派工详情

        /// <summary>
        /// 获取生产任务单明细的派工信息
        /// </summary>
        /// <param name="orderdetailId">任务单明细Id</param>
        /// <returns></returns>
        public async Task<List<OrderDetailDispatchDetailDTO>> GetOrderDetailDispatchDetailListAsync(string orderdetailId)
        {
            string sqlMain = @"select a.Id,a.ParentId,b.StaffName,a.SubId,c.`Name` as SubName,a.MaterialId,d.`Name` as MaterialName,d.Spec as MaterialSpec,d.IsVirtualkey,d.IsProduct,a.SubordinateProduct,e.`Name` as SubordinateProductName,a.Nums,a.WorkReportQuantity,f.Productionquantity,f.CompleteNums,a.CreatorRealName from PB_DispatchDetail as a
              left join PB_Dispatch as b on a.ParentId=b.Id
              left join PB_ProcecureSub as c on a.SubId=c.Id
              left join PB_Material as d on a.MaterialId=d.Id
              left join PB_Material as e on a.SubordinateProduct=e.Id
              left join PB_ProductionOrderDetail as f on a.OrderDetailId=f.Id
              where a.OrderDetailId='{0}' and b.State <>1  order by a.CreateTime ";
            string sql = string.Format(sqlMain, orderdetailId);
            return await Db.GetListBySqlAsync<OrderDetailDispatchDetailDTO>(sql);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task UpdateTaskDetailList(PB_ProductionOrderListUpdateDTO data)
        {
            List<PB_ProductionOrderDetail> pB_ProductionOrderDetails = new List<PB_ProductionOrderDetail>();
            //获取为派工的数据
            string strid = "";
            foreach (var item in data.Ids)
            {
                strid += "'" + item + "',";
            }
            strid = strid.Substring(0, strid.Length - 1);
            await ExecuteSqlAsync("delete from PB_ProductionOrderDetail where Id in (" + strid + ")");
            if (data.subData.Count>0) {
                foreach (var item in data.subData)
                {
                    PB_ProductionOrderDetail pB_ProductionOrderDetail = new PB_ProductionOrderDetail();
                    pB_ProductionOrderDetail.Id = IdHelper.GetId();
                    pB_ProductionOrderDetail.ParentId = data.Id;
                    pB_ProductionOrderDetail.MaterialId = item.MaterialId;
                    pB_ProductionOrderDetail.ProcecureId = item.ProcecureId;
                    pB_ProductionOrderDetail.Nums = item.Nums;
                    pB_ProductionOrderDetail.Remarks = item.Remarks;
                    pB_ProductionOrderDetail.StartDate = data.BeginDate;
                    pB_ProductionOrderDetail.EndDate = DateTime.Now;
                    pB_ProductionOrderDetail.CreateTime = DateTime.Now;
                    pB_ProductionOrderDetail.CreatorId = _operator.UserId;
                    pB_ProductionOrderDetail.Deleted = false;
                    pB_ProductionOrderDetail.HasCheck = true;
                    pB_ProductionOrderDetail.QrCode = "03," + pB_ProductionOrderDetail.Id;
                    pB_ProductionOrderDetail.WorkshopId = data.DeptId;
                    pB_ProductionOrderDetail.StationId = "";
                    pB_ProductionOrderDetail.Finishedproduct = item.Finishedproduct;
                    pB_ProductionOrderDetail.Ofmaterial = item.Ofmaterial;
                    pB_ProductionOrderDetail.Holespacing = item.Holespacing;
                    pB_ProductionOrderDetail.Productionquantity = item.Productionquantity;
                    pB_ProductionOrderDetail.CompleteNums = 0;
                    pB_ProductionOrderDetail.State = 0;
                    pB_ProductionOrderDetails.Add(pB_ProductionOrderDetail);
                }
                await Db.InsertAsync<PB_ProductionOrderDetail>(pB_ProductionOrderDetails);
            }
           
        }

        /// <summary>
        /// 任务单物料变更
        /// </summary>
        /// <returns></returns>
        [Transactional]
        public async Task ChangeTaskDetail(ChangeTaskDetailDto data)
        {
            string sql = string.Empty;
            var _pB_ProductionOrderDetail = await Db.GetIQueryable<PB_ProductionOrderDetail>().Where(m=>m.Id==data.OrderDetailId).FirstOrDefaultAsync();
            sql = "update  PB_ProductionOrderDetail set Remarks='"+data.Remarks+ "' , MaterialId='"+data.ReplacementMateraiId+"'  where  Id='" + data.OrderDetailId+"' ;";
            string detailId = IdHelper.GetId();
            //插入替换后的任务单明细
            PB_ProductionOrderDetail pB_ProductionOrderDetail = new PB_ProductionOrderDetail();
            pB_ProductionOrderDetail.Id = detailId;
            pB_ProductionOrderDetail.ParentId = _pB_ProductionOrderDetail.ParentId;
            pB_ProductionOrderDetail.MaterialId = data.OriginalMateraiId;
            pB_ProductionOrderDetail.ProcecureId = _pB_ProductionOrderDetail.ProcecureId;
            pB_ProductionOrderDetail.Nums = _pB_ProductionOrderDetail.Nums;
            pB_ProductionOrderDetail.Remarks = _pB_ProductionOrderDetail.Remarks;
            pB_ProductionOrderDetail.StartDate = _pB_ProductionOrderDetail.StartDate;
            pB_ProductionOrderDetail.EndDate = _pB_ProductionOrderDetail.EndDate;
            pB_ProductionOrderDetail.CreateTime = DateTime.Now;
            pB_ProductionOrderDetail.CreatorId = _operator.UserId;
            pB_ProductionOrderDetail.Deleted = false;
            pB_ProductionOrderDetail.HasCheck = _pB_ProductionOrderDetail.HasCheck;
            pB_ProductionOrderDetail.QrCode = "03,"+detailId;
            pB_ProductionOrderDetail.WorkshopId = _pB_ProductionOrderDetail.WorkshopId;
            pB_ProductionOrderDetail.StationId = _pB_ProductionOrderDetail.StationId;
            pB_ProductionOrderDetail.Finishedproduct = _pB_ProductionOrderDetail.Finishedproduct;
            pB_ProductionOrderDetail.Ofmaterial = _pB_ProductionOrderDetail.Ofmaterial;
            pB_ProductionOrderDetail.Holespacing = _pB_ProductionOrderDetail.Holespacing;
            pB_ProductionOrderDetail.Productionquantity = _pB_ProductionOrderDetail.Productionquantity;
            pB_ProductionOrderDetail.CompleteNums = 0;
            pB_ProductionOrderDetail.State = 0;

            //修改派工单明细
            var pb_dispatchdetailList =await Db.GetIQueryable<PB_DispatchDetail>().Where(m=>m.OrderDetailId==data.OrderDetailId).ToListAsync();
            if (pb_dispatchdetailList.Count>0) {
                foreach (var item in pb_dispatchdetailList) {
                    sql += "update  PB_DispatchDetail set SubordinateProduct='"+data.ReplacementMateraiId+"' WHERE Id='"+item.Id+"' ; ";
                }
            }
            List<String> ids = new List<string>();
            //修改流转单隶属成品
            var PB_CirculationBill = await Db.GetIQueryable<PB_CirculationBill>().Where(m => m.TaskDetailId == data.OrderDetailId).ToListAsync();
            if (PB_CirculationBill.Count > 0)
            {
                foreach (var item in PB_CirculationBill)
                {
                    sql += "update  PB_CirculationBill set SubordinateProduct='" + data.ReplacementMateraiId + "' WHERE Id='" + item.Id + "' ; ";
                    ids.Add(item.Id);
                }
            }
            var PB_JobBooking = await Db.GetIQueryable<PB_JobBooking>().Where(m =>ids.Contains(m.CirBillId)).ToListAsync();
            if (PB_JobBooking.Count > 0)
            {
                foreach (var item in PB_JobBooking)
                {
                    sql += "update  PB_JobBooking set MaterialId='" + data.ReplacementMateraiId + "' WHERE Id='" + item.Id + "' ; ";
                  
                }
            }
            sql += "update PB_ProductionOrder set Taskstatus=1 where Id='" + _pB_ProductionOrderDetail .ParentId+ "'";
            await Db.InsertAsync(pB_ProductionOrderDetail);
            await Db.ExecuteSqlAsync(sql);
        }
        public async Task ReplaceTask(Entity.DTO.PB_ProductionOrderListDTO data) {

            string sql = string.Empty;
            Base_User bdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            List<PB_ProductionOrderDetail> pB_ProductionOrderDetails = new List<PB_ProductionOrderDetail>();
            string Id = IdHelper.GetId();
            PB_ProductionOrder b_ProductionOrder = new PB_ProductionOrder
            {
                Id = Id,//编号
                Code = data.Code,//生产订单编号
                DesignId = data.DesignId,//生产订单编号
                POName = data.POName+"("+(DateTime.Now+"自生产")+")",//生产订单名称
                Type = data.Type,//生产订单类别
                BeginDate = data.BeginDate,//开始日期
                EndDate = data.EndDate,//结束日期
                Remarks = data.Remarks,//备注
                DeptId = data.DeptId,//组织id
                CreateTime = data.CreateTime,//创建时间
                CreatorId = data.CreatorId,//创建人id
                Deleted = data.Deleted,//是否删除
                Status = 1,//默认生产中 0 生产中  1已完成  2 作废
                Taskstatus = 0,//任务单状态 0 正常  1异常  
                BatchNumber = data.BatchNumber,
                State = data.State,
                IsNew = true,//是否为新生产 0否 1是
                IsRefurbishment =5,  //是否翻新
                QrCode = h_ProductionOrder + "," + Id,//二维码
            };
            await InsertAsync(b_ProductionOrder);
            foreach (var item in data.subData) {
                string DetailId = IdHelper.GetId();
                PB_ProductionOrderDetail pB_ProductionOrderDetail = new PB_ProductionOrderDetail();
                pB_ProductionOrderDetail.Id = DetailId;//id
                pB_ProductionOrderDetail.ParentId = Id;//主表信息
                pB_ProductionOrderDetail. MaterialId = item.MaterialId;//物料编号
                pB_ProductionOrderDetail.ProcecureId = item.ProcecureId;//工序编号
                pB_ProductionOrderDetail.Nums = item.Nums;//计划数量
                pB_ProductionOrderDetail.Remarks = item.Remarks;//备注
                pB_ProductionOrderDetail.StartDate = item.StartDate;//开工日期
                pB_ProductionOrderDetail.EndDate = item.EndDate;//完工日期
                pB_ProductionOrderDetail.CreateTime = DateTime.Now;
                pB_ProductionOrderDetail.CreatorId = _operator.UserId;//创建人
                pB_ProductionOrderDetail.Deleted = false;//为删除
                pB_ProductionOrderDetail.HasCheck = true;//是否质检
                pB_ProductionOrderDetail.QrCode = h_ProductionOrderDetail + "," + Id + "," + DetailId; //条形码
                pB_ProductionOrderDetail.WorkshopId = item.WorkshopId;//车间
                pB_ProductionOrderDetail.StationId = item.StationId;//公位
                pB_ProductionOrderDetail.Finishedproduct = item.Finishedproduct;//成品
                pB_ProductionOrderDetail.Ofmaterial = item.Ofmaterial;//材质
                pB_ProductionOrderDetail.Holespacing = item.Holespacing;//孔距
                pB_ProductionOrderDetail.Productionquantity = item.Productionquantity;//生产数量
                pB_ProductionOrderDetail.CompleteNums = 0;     //已完成数量
                pB_ProductionOrderDetail.State = 0;
                pB_ProductionOrderDetails.Add(pB_ProductionOrderDetail);
                //修改派工单明细
                var pb_dispatchdetailList = await Db.GetIQueryable<PB_DispatchDetail>().Where(m => m.OrderDetailId == item.Id).ToListAsync();
                if (pb_dispatchdetailList.Count > 0)
                {
                    foreach (var items in pb_dispatchdetailList)
                    {
                        sql += "update  PB_DispatchDetail set OrderDetailId='" + DetailId + "' ,OrderId='"+Id+ "' WHERE OrderDetailId='" + item.Id + "' ; ";
                    }
                }

                List<String> ids = new List<string>();
                //修改流转单隶属成品
                var PB_CirculationBill = await Db.GetIQueryable<PB_CirculationBill>().Where(m => m.TaskDetailId == item.Id).ToListAsync();
                if (PB_CirculationBill.Count > 0)
                {
                    foreach (var itemcill in PB_CirculationBill)
                    {
                        sql += "update  PB_CirculationBill set TaskDetailId='" + DetailId + "' ,TaskId='"+Id+ "'  WHERE TaskDetailId='" + item.Id + "' ; ";
                        ids.Add(itemcill.Id);
                    }
                }

                var PB_JobBooking = await Db.GetIQueryable<PB_JobBooking>().Where(m => ids.Contains(m.CirBillId)).ToListAsync();
                if (PB_JobBooking.Count > 0)
                {
                    foreach (var pB_JobBooking in PB_JobBooking)
                    {
                        sql += "update  PB_JobBooking set ParentId='" + DetailId + "' WHERE Id='" + pB_JobBooking.Id + "' ; ";

                    }
                }

                //修改派工与流转单关系对应关系表
                var pb_DispatchGroup = await Db.GetIQueryable<PB_DispatchGroup>().Where(m => m.TaskDetailId == item.Id).ToListAsync();
                if (pb_DispatchGroup.Count > 0)
                {
                    foreach (var items in pb_dispatchdetailList)
                    {
                        sql += "update  PB_DispatchDetail set TaskId='" + Id + "' ,TaskDetailId='" + DetailId + "' WHERE OrderDetailId='" + item.Id + "' ; ";
                    }
                }
            }
           
            await Db.InsertAsync<PB_ProductionOrderDetail>(pB_ProductionOrderDetails);
            await Db.ExecuteSqlAsync(sql);
        }

        public async Task<List <CirculationDetails>>PrintCirculationDetails(string DispatchDtailId, string SubId)
        {
            List<CirculationDetails> circulationDetails = new List<CirculationDetails>();

         
            Expression<Func<PB_CirculationBill, PB_ProductionOrder, PB_ProcecureSub, Base_User,PB_Dispatch,PB_ShiftType,PB_Material,PB_Material,PB_DispatchDetail,CirculationDetails>> selects = (a, b, c,d,e,f,g,h,j) => new CirculationDetails
            {
              POName=b.POName,
              SubName=c.Name,
                RealName=d.RealName,
                TempName=f.Name,
                SingleWeight=g.Weight==null?0:g.Weight,
                TotalWeight=a.WorkReportQuantity*(g.Weight==null?0:g.Weight),
                ProductName=h.Name,
                WorkpieceName=g.Name,
                Spec=g.Spec,
                DispatchNums=a.Reamrk,
            };
            selects = selects.BuildExtendSelectExpre();
            var qdata = from a in Db.GetIQueryable<PB_CirculationBill>().AsExpandable()
                        join b in Db.GetIQueryable<PB_ProductionOrder>() on a.TaskId equals b.Id into ab
                        from b in ab.DefaultIfEmpty()
                        join c in Db.GetIQueryable<PB_ProcecureSub>() on a.ProcedureId equals c.Id into ac
                        from c in ac.DefaultIfEmpty()
                        join d in Db.GetIQueryable<Base_User>() on a.WorkerId equals d.Id into ad
                        from d in ad.DefaultIfEmpty()
                        join e in Db.GetIQueryable<PB_Dispatch>() on a.DispatchId equals e.Id into ae
                        from e in ae.DefaultIfEmpty()
                        join f in Db.GetIQueryable<PB_ShiftType>() on e.TeamType equals f.Id into ef
                        from f in ef.DefaultIfEmpty()
                        join g in Db.GetIQueryable<PB_Material>() on a.MaterialId equals g.Id into ag
                        from g in ag.DefaultIfEmpty()
                        join h in Db.GetIQueryable<PB_Material>() on a.SubordinateProduct equals h.Id into ah
                        from h in ah.DefaultIfEmpty()
                        join j in Db.GetIQueryable<PB_DispatchDetail>() on a.DispatchDetailId equals j.Id into aj
                        from j in aj.DefaultIfEmpty()
                        select @selects.Invoke(a, b, c,d,e,f,g,h,j);
            circulationDetails = await qdata.Where(x => x.DispatchDetailId == DispatchDtailId&&x.ProcedureId==SubId).ToListAsync();
            if (circulationDetails .Count>0)
            {
                return circulationDetails;
            }
            throw new BusException("流转单不存在");
            
        }



        #endregion

        #region 私有成员

        #endregion
    }
}